場景描述
如果在你的工程代碼已經(jīng)寫好了,面臨交貨,突然這個時候產(chǎn)品說,要讓6和6P的字體大小不一樣...233這個時候,就尷尬了。不過對于你界面上的控件是純代碼創(chuàng)建的,這個時候,嘿嘿,就有很好的方法了,通過runtime替換系統(tǒng)字體大方法systemFontOfSize:
方法就能很快實(shí)現(xiàn)了。但是這樣也有個缺陷,如果是用xib創(chuàng)建的控件,并設(shè)置的字體大小,嘿嘿。那可有得搞了。需要手動在awakeFromNib
方法里面手動設(shè)置(哭臉).
runtime替換方法
對于runtime的內(nèi)容,就不再這里細(xì)說了,runtime能實(shí)現(xiàn)的東西很多,用runtime能實(shí)現(xiàn)很多裝逼特技。
實(shí)現(xiàn)步驟
- 先定義好不同機(jī)型的宏
- 給UIFont添加一個分類
- 在這個分類里面實(shí)現(xiàn)自定義的設(shè)置字體的方法
- 重載系統(tǒng)的load方法,實(shí)現(xiàn)自定義方法和系統(tǒng)方法的替換。
1.新建UIFont的分類
這個步驟就不細(xì)說了,也很簡單。就是command + N, 然后選擇對應(yīng)選項(xiàng)。
2.在分類中添加不同機(jī)型的宏,以及不同機(jī)型上的字體號數(shù)的對應(yīng)改變量。
// 設(shè)備
#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 )
// 放大的字號數(shù)
#define IPHONE6_INCREMENT 2
#define IPHONE6PLUS_INCREMENT 3
這里的放大字號數(shù)的意思是,如果設(shè)置的系統(tǒng)字體大小為15,那么在4、5上面的大小就是15,而在6上就增加2,即17,在6P上就增加3,即18。具體改變多少根據(jù)需求設(shè)定。這個為了顯示出區(qū)別,暫且改為10便于觀察。
3. 添加自定義方法,實(shí)現(xiàn)不同機(jī)型不同字體
+ (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交換系統(tǒng)的systemFontOfSize:
方法和自定義方法
- 要使用runtime,那么就需要導(dǎo)入相應(yīng)的頭文件:
#import <objc/runtime.h>
- 然后在
+(void)load
方法中實(shí)現(xiàn)替換。(load
方法在該分類到內(nèi)存的時候調(diào)用,比init
方法先調(diào)用) - 獲取類方法用
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并設(shè)置字體大小,分別用5s和6運(yùn)行查看。
- (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];
}
效果:
5s和6的字體大小不一樣
6.總結(jié)
雖然這樣能實(shí)現(xiàn),但是systemFontOfSize方法只是用存代碼寫的控件的時候用啊 如果是用xib寫的控件,并設(shè)置了字體就不行了
。那如果是用xib
寫的UI,有什么好的方法呢?
- 提供了一種思路,在VC里面重寫
layoutSubViews
方法,遞歸遍歷所有的控件,設(shè)置font。