场景描述
如果在你的工程代码已经写好了,面临交货,突然这个时候产品说,要让6和6P的字体大小不一样...233这个时候,就尴尬了。不过对于你界面上的控件是纯代码创建的,这个时候,嘿嘿,就有很好的方法了,通过runtime替换系统字体大方法systemFontOfSize:
方法就能很快实现了。但是这样也有个缺陷,如果是用xib创建的控件,并设置的字体大小,嘿嘿。那可有得搞了。需要手动在awakeFromNib
方法里面手动设置(哭脸).
runtime替换方法
对于runtime的内容,就不再这里细说了,runtime能实现的东西很多,用runtime能实现很多装逼特技。
实现步骤
- 先定义好不同机型的宏
- 给UIFont添加一个分类
- 在这个分类里面实现自定义的设置字体的方法
- 重载系统的load方法,实现自定义方法和系统方法的替换。
1.新建UIFont的分类
这个步骤就不细说了,也很简单。就是command + N, 然后选择对应选项。
2.在分类中添加不同机型的宏,以及不同机型上的字体号数的对应改变量。
// 设备
#define IS_IPAD [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
#define IS_IPHONE [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone
#define IS_IPHONE_4 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )480) < DBL_EPSILON )
#define IS_IPHONE_5 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )568) < DBL_EPSILON )
#define IS_IPHONE_6 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )667) < DBL_EPSILON )
#define IS_IPHONE_6_PLUS (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )960) < DBL_EPSILON )
// 放大的字号数
#define IPHONE6_INCREMENT 2
#define IPHONE6PLUS_INCREMENT 3
这里的放大字号数的意思是,如果设置的系统字体大小为15,那么在4、5上面的大小就是15,而在6上就增加2,即17,在6P上就增加3,即18。具体改变多少根据需求设定。这个为了显示出区别,暂且改为10便于观察。
3. 添加自定义方法,实现不同机型不同字体
+ (UIFont *)adjustFont:(CGFloat)fontSize{
UIFont * newFont = nil;
if (IS_IPHONE_6) {
newFont = [UIFont adjustFont:fontSize + IPHONE6_INCREMENT];
}else if (IS_IPHONE_6_PLUS){
newFont = [UIFont adjustFont:fontSize + IPHONE6PLUS_INCREMENT];
}else{
newFont = [UIFont adjustFont:fontSize];
}
return newFont;
}
4.利用runtime交换系统的systemFontOfSize:
方法和自定义方法
- 要使用runtime,那么就需要导入相应的头文件:
#import <objc/runtime.h>
- 然后在
+(void)load
方法中实现替换。(load
方法在该分类到内存的时候调用,比init
方法先调用) - 获取类方法用
class_getClassMethod
,获取对象方法用class_getInstanceMethod
+(void)load{
// 获取交换后的方法
Method newMethod = class_getClassMethod([self class], @selector(adjustFont:));
// 获取替换前的方法
Method method = class_getClassMethod([self class], @selector(systemFontOfSize:));
// 交换
method_exchangeImplementations(newMethod, method);
}
5. 测试
在VC里面添加一个label并设置字体大小,分别用5s和6运行查看。
- (void)viewDidLoad {
[super viewDidLoad];
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 50)];
label.font = [UIFont systemFontOfSize:15];
label.text = @"字体测试";
[self.view addSubview:label];
}
效果:
6.总结
虽然这样能实现,但是systemFontOfSize方法只是用存代码写的控件的时候用啊 如果是用xib写的控件,并设置了字体就不行了
。那如果是用xib
写的UI,有什么好的方法呢?
- 提供了一种思路,在VC里面重写
layoutSubViews
方法,递归遍历所有的控件,设置font。