最近在項(xiàng)目中,被要求將系統(tǒng)的蘋方體全部更換為三方字體,其實(shí)更換全部字體相對(duì)比更換部分字體來的簡(jiǎn)單,我們可以使用runtime來解決.
將字體添加到項(xiàng)目中
-
將字體拖入系統(tǒng)resource中, 注意選擇add to taget選項(xiàng)
-
打開Target 的Build Phases --> Copy Bundle Resource 看一下字體是否在這個(gè)標(biāo)簽下 如果沒有 點(diǎn)擊 + 添加一下即可.
-
然后點(diǎn)擊 info 選項(xiàng), 添加一個(gè)字段 Fonts provided by application 這是一個(gè)數(shù)組, 在數(shù)組中添加 item 每個(gè)item 就是字體的名字.
使用字體
- 注意: 添加進(jìn)的.tff文件可能不是字體真正的名字, 我們需要遍歷找到剛剛添加的字體.用一下代碼遍歷查找, 添加到appDelegate的didFinishLaunchingWithOptions方法中即可.
for(NSString *fontFamilyName in [UIFont familyNames]) {
NSLog(@"fontFamilyName:'%@'",fontFamilyName);
for(NSString *fontName in [UIFont fontNamesForFamilyName:fontFamilyName]) {
NSLog(@" font:'%@'",fontName);
}
NSLog(@"*****************************");
}
區(qū)域更換字體(更換某個(gè)UILabel的字體)
- 找到字體名字就可以使用這個(gè)三方字體了, 可以用
[UIFont fontWithName:@"" size:];
更換全部文字的字體
替換 UILabel 的方法
筆者在接到更換字體需求的時(shí)候幾乎已經(jīng)快完成項(xiàng)目了,單個(gè)UILabel更換顯然已經(jīng)是不太可能了.網(wǎng)上搜索發(fā)現(xiàn)可以使用runtime來在運(yùn)行時(shí)更換UILabel的方法.
+load 方法在加載類的時(shí)候就被調(diào)用, iOS 應(yīng)用啟動(dòng)的時(shí)候伤疙,就會(huì)加載所有的類,所以就會(huì)調(diào)用每個(gè)類的 +load 方法辆影。
在 +load 方法中 替換UILabel的可能的初始化方法,在新方法里面設(shè)置UILabel的字體,這樣就更換了所有UILabel的字體.
注意:在重寫+load的時(shí)候 要先給父類初始化 調(diào)用
[super load]
方法. 然后使用GCD創(chuàng)建一個(gè)dispatch_once_t 保證這段代碼只執(zhí)行一次.系統(tǒng)的初始化方法和自定義的方法 在runtime中都是 SEL類型. 創(chuàng)建兩個(gè)方法.要實(shí)現(xiàn)自定的方法設(shè)置字體. 例如:
SEL originalSelector = @selector(init);
SEL swizzledSelector = @selector(QQInit);
分別get兩個(gè)實(shí)例方法
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
然后我們直接替換兩個(gè)方法即可
method_exchangeImplementations(originalMethod, swizzledMethod);
- 自定義方法的實(shí)現(xiàn)
- (instancetype)QQInit {
id __self = [self QQInit];
UIFont * font = [UIFont fontWithName:@"FZSEK--GBK1-0" size:self.font.pointSize];
if (font) {
self.font=font;
}
return __self;
}
替換 UIFont 的方法
上面完成之后我們會(huì)發(fā)現(xiàn)有一部分的字體沒有被替換, 可能是因?yàn)槲覀冊(cè)赨ILabel初始化之后又調(diào)用了一下幾個(gè)方法 這幾個(gè)方法中有設(shè)置systemFont的作用.所以又被設(shè)置為系統(tǒng)的蘋方字了,所以我們還要使用runtime來替換UIFont的這幾個(gè)方法.
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize;
+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize;
+ (UIFont *)italicSystemFontOfSize:(CGFloat)fontSize;
替換方法是一樣的,只不過這幾個(gè)方法是類方法, 所以在getMethod的時(shí)候就不能使用
class_getInstanceMethod
而要使用class_getClassMethod
自定義方法的實(shí)現(xiàn)
+(UIFont *)QQsystemFontOfSize:(CGFloat)fontSize {
UIFont * font = [UIFont fontWithName:@"FZSEK--GBK1-0" size:fontSize];
if (!font) {
return [self QQsystemFontOfSize:fontSize];
}
return font;
}
Test
UILabel *lab = [[UILabel alloc] initWithFrame:self.view.bounds];
lab.text = @"按時(shí)到合肥拉薩交電話費(fèi)拉還是快遞費(fèi)盧卡斯 阿薩德會(huì)盡快了粉紅色的拉客戶放假啦是肯定會(huì)發(fā)生良好的會(huì)計(jì)法哈收了的看法和沙拉肯定會(huì)發(fā)了卡薩丁";
lab.font = [UIFont systemFontOfSize:19];
lab.numberOfLines = 0;
[self.view addSubview:lab];
- 上面的代碼設(shè)置了文字,也是設(shè)置了系統(tǒng)文字的大小,但是并不妨礙我們更換字體.
參考文章-->地址
GitHub-->Demo地址