忙忙忙!@パ省驾凶!好久沒寫博客了,前段時間實在是每天滿滿的掷酗,回去了累了也不想寫了调违,只是躺床上看一會東西。最近公司要在5月份舉辦個大型的發(fā)布會泻轰,所以在這之前要把版本穩(wěn)定技肩,界面提升,所以有很多細活要干浮声。
不過虚婿,趁前兩天版本剛提交上線,這兩天稍微閑一點泳挥,就把之前說的利用
runtime
一鍵改變字體的方法分享出來然痊。有人會說,改變字體不是很簡單嗎屉符,我直接找到字體名替換一下不就好了剧浸?客官不要急锹引,先坐下來吃點瓜子,聽我慢慢給你說來唆香。
1嫌变、準備
我們新建一個項目名叫ChangeFont
,然后我就隨便找了個名叫loveway.ttf
的字體庫拖進去躬它,里面的工程目錄大概就是這樣的
現(xiàn)在我們就簡單的直接在
storyboard
上拖了一個label
一個button
腾啥,約束好,像這樣
嗯虑凛,就這樣碑宴,很簡單软啼,運行
好的顯示正常桑谍,沒什么問題,接下來改變字體祸挪。
2锣披、改變字體
我們之前已經(jīng)把loveway.ttf
這個文件拖進去了,現(xiàn)在在plist
文件里面配置一下贿条。打開plist
然后加入名為Fonts provided by application
的一行雹仿,在item
里把我們的字體名字加進去
最后我們需要保證我們確確實實是加進來了
這個時候也許你已經(jīng)迫不及待了,趕緊改字體整以,如下
//
// ViewController.m
// ChangeFont
//
// Created by HenryCheng on 16/4/27.
// Copyright ? 2016年 HenryCheng. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_myLabel.font = [UIFont fontWithName:@"loveway.ttf" size:17.0f];
_myButton.titleLabel.font = [UIFont fontWithName:@"loveway" size:17.0f];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
運行胧辽。。公黑。oh no 邑商!怎么沒變,還是原來的樣子
肯定是姿勢不對凡蚜,于是百度了一下(雖然我一般都用谷歌)人断,的確這種方法不對
于是改變思路,先找出字體的名字朝蜘,Like this恶迈,代碼改成這樣
- (void)viewDidLoad {
[super viewDidLoad];
for(NSString *familyName in [UIFont familyNames]){
NSLog(@"Font FamilyName = %@",familyName); //*輸出字體族科名字
for(NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
NSLog(@"\t%@",fontName); //*輸出字體族科下字樣名字
}
}
_myLabel.font = [UIFont fontWithName:@"loveway.ttf" size:17.0f];
_myButton.titleLabel.font = [UIFont fontWithName:@"loveway" size:17.0f];
}
運行一看控制臺
這什么鬼,我哪知道我剛加進去的字體名稱是什么谱醇,這咋找
于是想出來個辦法暇仲,再建一個工程,不加入
loveway.ttf
這個字體副渴,打印出來熔吗,一個個對比,多的那個不就是了嗎佳晶!bingo桅狠,于是花了一會功夫終于找出來了,是FZLBJW--GB1-0
,不管了中跌,先試試看行不行

- (void)viewDidLoad {
[super viewDidLoad];
/*
for(NSString *familyName in [UIFont familyNames]){
NSLog(@"Font FamilyName = %@",familyName); //輸出字體族科名字
for(NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
NSLog(@"\t%@",fontName); //輸出字體族科下字樣名字
}
}
*/
_myLabel.font = [UIFont fontWithName:@"FZLBJW--GB1-0" size:17.0f];
_myButton.titleLabel.font = [UIFont fontWithName:@"FZLBJW--GB1-0" size:17.0f];
}
運行咨堤,結(jié)果如下
OK!達到效果了漩符,雖然有點挫一喘,但是效果達到了,還不錯
到這里嗜暴,基本的改變字體效果已達到凸克。
3、查找字體的一種簡單的方法
在上面我們可以看到闷沥,通過對比的方法找到了FZLBJW--GB1-0
這個名字萎战,這里,有一種簡單的方法舆逃,
我們在 Finder 里面找到這個ttf
蚂维,雙擊打開(在Xcode
里面雙擊打開沒效果),這時候系統(tǒng)就會用蘋果自帶的字體冊打開路狮,如下
這樣我們就可以看到了這個字體的族科名字虫啥,我們看到的是
FZLiBian-S02S
,于是我們在剛才輸出全部字體名的控制臺搜索一下這個族科名奄妨,就可以知道具體的字體名了
這樣就比上面簡單多了涂籽。
4、進一步的思考
上面例子中簡單的說了一下改變字體的方法砸抛,雖然成功了评雌,但是我們不得不思考一下。上面只是兩個簡單的控件锰悼,那么我要是有一堆控件怎么辦柳骄?或者你可以說我也可用這種方法一個個加,你要是純代碼寫的還好箕般,你要是xib
寫的耐薯,難道還要把一個個無用的只是顯示一下的label
或者button
拉出來這樣寫嗎?這樣的話丝里,效率肯定會非常低曲初,尤其是那些寫到一半的大工程,感覺這種方法肯定是行不通的杯聚。
這里利用runtime
的class_addMethod
臼婆、class_replaceMethod
、method_exchangeImplementations
這幾個方法幌绍,然后根據(jù)+ (void)load
這個方法的特性實現(xiàn)(關(guān)于+ (void)load
這個方法后面會說颁褂,或者不懂得童鞋可以先查查資料)故响,代碼如下
//
// UILabel+FontChange.m
// LiquoriceDoctorProject
//
// Created by HenryCheng on 15/12/7.
// Copyright ? 2015年 iMac. All rights reserved.
//
#import "UILabel+FontChange.h"
#import <objc/runtime.h>
#define CustomFontName @"FZLBJW--GB1-0"
@implementation UILabel (FontChange)
+ (void)load {
//方法交換應(yīng)該被保證,在程序中只會執(zhí)行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//獲得viewController的生命周期方法的selector
SEL systemSel = @selector(willMoveToSuperview:);
//自己實現(xiàn)的將要被交換的方法的selector
SEL swizzSel = @selector(myWillMoveToSuperview:);
//兩個方法的Method
Method systemMethod = class_getInstanceMethod([self class], systemSel);
Method swizzMethod = class_getInstanceMethod([self class], swizzSel);
//首先動態(tài)添加方法颁独,實現(xiàn)是被交換的方法彩届,返回值表示添加成功還是失敗
BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
if (isAdd) {
//如果成功,說明類中不存在這個方法的實現(xiàn)
//將被交換方法的實現(xiàn)替換到這個并不存在的實現(xiàn)
class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
} else {
//否則誓酒,交換兩個方法的實現(xiàn)
method_exchangeImplementations(systemMethod, swizzMethod);
}
});
}
- (void)myWillMoveToSuperview:(UIView *)newSuperview {
[self myWillMoveToSuperview:newSuperview];
// if ([self isKindOfClass:NSClassFromString(@"UIButtonLabel")]) {
// return;
// }
if (self) {
if (self.tag == 10086) {
self.font = [UIFont systemFontOfSize:self.font.pointSize];
} else {
if ([UIFont fontNamesForFamilyName:CustomFontName])
self.font = [UIFont fontWithName:CustomFontName size:self.font.pointSize];
}
}
}
@end
然后不加任何代碼如下
//
// ViewController.m
// ChangeFont
//
// Created by HenryCheng on 16/4/27.
// Copyright ? 2016年 HenryCheng. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// for(NSString *familyName in [UIFont familyNames]){
// NSLog(@"Font FamilyName = %@",familyName); //輸出字體族科名字
//
// for(NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
// NSLog(@"\t%@",fontName); //輸出字體族科下字樣名字
// }
// }
// _myLabel.font = [UIFont fontWithName:@"FZLBJW--GB1-0" size:17.0f];
// _myButton.titleLabel.font = [UIFont fontWithName:@"FZLBJW--GB1-0" size:17.0f];
// _myLabel.tag = 10086;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
運行
我們可以看到字體改變了樟蠕。
如果有人說我有的想改變字體有的不想改變字體怎么辦,我這里有個簡單的辦法就是設(shè)置
tag
靠柑,比如我設(shè)置label
的tag
為10086
(隨便起的)寨辩,就讓他字體不改變
運行結(jié)果
注意:
1、如果你是代碼寫控件歼冰,你不想改變字體靡狞,你只需在創(chuàng)建的時候設(shè)置tag
為10086
2、上面代碼中注釋了一行
// if ([self isKindOfClass:NSClassFromString(@"UIButtonLabel")]) {
// return;
// }
這個是當時寫的時候不改變button
的title
字體設(shè)置的停巷,在這里你可以判斷那種類型的改哪種不改耍攘,比如說你不想改button
的字體榕栏,把這一句解注釋即可
3畔勤、如果你是xib
拉的控件,你不想改變字體扒磁,你必須在xib
界面設(shè)置tag
為10086
庆揪,不可加載完畢后在- (void)viewDidLoad
里面設(shè)置,這還是因為+ (void)load
這個方法
- 在一個程序(main函數(shù))運行之前妨托,所用到的庫被加載到runtime之后缸榛,被添加到的runtime系統(tǒng)的各種類和category的+load方法就被調(diào)用;(關(guān)于這點很容易通過打印語句來驗證)兰伤;
- 如果父類和子類的+load方法都被調(diào)用内颗,父類的調(diào)用一定在子類之前,這是系統(tǒng)自動完成的敦腔,子類+load中沒必要顯式調(diào)用[super load];均澳;
這里只是簡單的說一下,具體不理解的可以翻翻官方文檔
5符衔、最后
關(guān)于代碼的解釋找前,在工程里都已經(jīng)注釋的非常清楚了,這里就不多說了判族,不清楚的童鞋可以給我留言躺盛。具體用法很簡單,你只需要將UILabel+FontChange.h
和UILabel+FontChange.m
拉進你的工程即可形帮。
需要下載更多字體的可以在 字體庫下載槽惫,所有的代碼都可以在 這里下載周叮。
最近在看swift
,做了一下筆記界斜,后面會為大家分享總結(jié)的一些swift tips
则吟。
最后,如果你有什么建議或者指正的地方請給我留言锄蹂,如果喜歡或者對你有幫助的話氓仲,就請star
一下吧,謝謝得糜!