場景描述
如果在你的工程代碼已經(jīng)寫好了,面臨交貨学赛,突然這個時候產(chǎn)品說叁巨,要讓6和6P的字體大小不一樣...233這個時候斑匪,就尷尬了。不過對于你界面上的控件是純代碼創(chuàng)建的锋勺,這個時候,嘿嘿狡蝶,就有很好的方法了庶橱,通過runtime替換系統(tǒng)字體大方法systemFontOfSize:
方法就能很快實現(xiàn)了。但是這樣也有個缺陷贪惹,如果是用xib創(chuàng)建的控件苏章,并設(shè)置的字體大小,嘿嘿奏瞬。那可有得搞了枫绅。需要手動在awakeFromNib
方法里面手動設(shè)置(哭臉).
runtime替換方法
對于runtime的內(nèi)容,就不再這里細說了硼端,runtime能實現(xiàn)的東西很多并淋,用runtime能實現(xiàn)很多裝逼特技。
實現(xiàn)步驟
- 先定義好不同機型的宏
- 給UIFont添加一個分類
- 在這個分類里面實現(xiàn)自定義的設(shè)置字體的方法
- 重載系統(tǒng)的load方法珍昨,實現(xiàn)自定義方法和系統(tǒng)方法的替換县耽。
1.新建UIFont的分類
這個步驟就不細說了,也很簡單镣典。就是command + N兔毙, 然后選擇對應(yīng)選項。
2.在分類中添加不同機型的宏,以及不同機型上的字體號數(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. 添加自定義方法,實現(xiàn)不同機型不同字體
+ (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
方法中實現(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運行查看眼坏。
- (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.總結(jié)
雖然這樣能實現(xiàn),但是systemFontOfSize方法只是用存代碼寫的控件的時候用啊 如果是用xib寫的控件酸些,并設(shè)置了字體就不行了
宰译。那如果是用xib
寫的UI,有什么好的方法呢魄懂?
- 提供了一種思路沿侈,在VC里面重寫
layoutSubViews
方法,遞歸遍歷所有的控件市栗,設(shè)置font缀拭。