1、引言
由于公司產(chǎn)品經(jīng)理提出的需求审残,說不同機型下的字體變化不怎么明顯梭域,尤其是iPhone 5s,字體比較大维苔,固定的控件大小碰辅、位置就顯得比較擁擠;其他機型則還好介时,顯示比較正常。
2、效果
3沸柔、方案
1循衰、分純代碼和XIB/SB
1.純代碼
//初始化
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 25)];
label.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2-100);
CGFloat multiple = [self fontMultiple];
label.font = [UIFont systemFontOfSize:17.0*multiple];
label.text = @"①自動適配文字大小";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
[self.view addSubview:label];
}
//倍數(shù)
- (CGFloat)fontMultiple
{
CGFloat width = [UIScreen mainScreen].bounds.size.width;
if (width == 320) {
return FONT_IPHONE_5S;//0.7
}
else if (width == 375) {
return FONT_IPHONE_6;//1.0
}
else if (width == 414) {
return FONT_IPHONE_6P;//1.3
}
else {
return FONT_IPHONE_OTHER;//1.1
}
}
2.XIB/SB
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if (IS_IPHONE_5) {
_textLabel.font = [UIFont systemFontOfSize:12];
}
//XIB/SB中默認設(shè)置就是6和6p的文字大小
if (IS_iPhoneX) {
_textLabel.font = [UIFont systemFontOfSize:13];
}
}
2、使用分類+runtime交換方法實現(xiàn)
關(guān)于runtime的具體實戰(zhàn)請?zhí)D(zhuǎn):傳送門
1.UIFont
+ (void)load
{
[self exchangeMethod:@selector(systemFontOfSize:) with:@selector(SY_systemFontOfSize:)];
}
+ (UIFont *)SY_systemFontOfSize:(CGFloat)fontSize
{
//這里并不是循環(huán)調(diào)用褐澎,+load里已經(jīng)把這方法與系統(tǒng)的方法交換了会钝,因此這里調(diào)用的是系統(tǒng)方法
CGFloat multiple = [self fontMultiple];
UIFont *font = [self SY_systemFontOfSize:fontSize*multiple];
return font;
}
+ (CGFloat)fontMultiple
{
CGFloat width = [UIScreen mainScreen].bounds.size.width;
if (width == 320) {
return FONT_IPHONE_5S;
}
else if (width == 375) {
return FONT_IPHONE_6;
}
else if (width == 414) {
return FONT_IPHONE_6P;
}
else {
return FONT_IPHONE_OTHER;
}
}
+ (BOOL)exchangeMethod:(SEL)systemSel with:(SEL)newSel
{
Class class = object_getClass(self);
Method originalMethod = class_getInstanceMethod(class, systemSel);
Method newMethod = class_getInstanceMethod(class, newSel);
if (!originalMethod || !newMethod) return NO;
method_exchangeImplementations(originalMethod, newMethod);
return YES;
}
2.UILabel
+ (void)load
{
[[self class] exchangeMethod:@selector(initWithCoder:) with:@selector(SY_initWithCoder:)];
}
- (id)SY_initWithCoder:(NSCoder *)coder
{
[self SY_initWithCoder:coder];
CGFloat fontSize = self.font.pointSize;
self.font = [UIFont systemFontOfSize: fontSize];
return self;
}
+ (BOOL)exchangeMethod:(SEL)systemSel with:(SEL)newSel
{
Method originalMethod = class_getInstanceMethod(self, systemSel);
Method newMethod = class_getInstanceMethod(self, newSel);
if (!originalMethod || !newMethod) return NO;
class_addMethod(self,
systemSel,
class_getMethodImplementation(self, systemSel),
method_getTypeEncoding(originalMethod));
class_addMethod(self,
newSel,
class_getMethodImplementation(self, newSel),
method_getTypeEncoding(newMethod));
method_exchangeImplementations(class_getInstanceMethod(self, systemSel),
class_getInstanceMethod(self, newSel));
return YES;
}
3、兩種方案的對比
雖然實現(xiàn)的結(jié)果都一樣工三,但很明顯迁酸,第二種方案是最好的,因為只要在項目中加入這兩個分類俭正,就可以實現(xiàn)所有的(無論純代碼還是XIB/SB)label文字根據(jù)屏幕自動適配奸鬓。第一種方案,在純代碼下可以使用掸读,但XIB文件很多的話串远,就非常的麻煩。