- iOS動態(tài)加載字體有兩種方案
1.加載系統(tǒng)自帶字體, 雖然叫系統(tǒng)自帶字體, 但還是需要通過網(wǎng)絡下載. 系統(tǒng)自帶字體下載是由系統(tǒng)完成, 也不會存在app沙盒中. 一次下載永久存儲, 除非手機恢復出廠. 但是app使用前需要注冊下字體.
具體看代碼,注意下載的網(wǎng)絡請求會由系統(tǒng)發(fā)起,你不需要通過AFNetworking去管理.
+(void)vsc_fontWithPostScriptName:(NSString *)fontName
chsName:(NSString *)chsName
fontSize:(CGFloat)fontSize
progress:(void (^)(CGFloat progress))progress
complete:(void (^)(UIFont *font))complete
failure:(void (^)(NSError *error))failure{
if (!complete) {
return;
}
UIFont *existFont = [self existFontWithPostScriptName:fontName fontSize:fontSize];
if (existFont) {
complete(existFont);
return;
}
//用字體的PostScript名字創(chuàng)建一個Dictionary
NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];
// 創(chuàng)建一個字體描述對象CTFontDescriptorRef
CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);
//將字體描述對象放到一個NSMutableArray中
NSMutableArray *descs = [NSMutableArray arrayWithCapacity:0];
[descs addObject:(__bridge id)desc];
CFRelease(desc);
__block BOOL errorDuringDownload = NO;
//開始對字體進行下載
CTFontDescriptorMatchFontDescriptorsWithProgressHandler( (__bridge CFArrayRef)descs, NULL, ^(CTFontDescriptorMatchingState state, CFDictionaryRef progressParameter) {
CGFloat progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] floatValue];
switch (state) {
case kCTFontDescriptorMatchingDidBegin:{//字體已經(jīng)匹配
}
break;
case kCTFontDescriptorMatchingDidFinish:{//字體下載完成
if (!errorDuringDownload) {
dispatch_async(dispatch_get_main_queue(), ^{
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
complete(font);
});
}
}
break;
case kCTFontDescriptorMatchingWillBeginDownloading:{//字體開始下載
// [self downloadAlertWithPostScriptName:fontName chsName:chsName];
if (needToReask) {
needToReask = NO;
errorDuringDownload = YES;
return (bool)NO;
}
}
break;
case kCTFontDescriptorMatchingDidFinishDownloading:{//字體下載完成
dispatch_async(dispatch_get_main_queue(), ^{
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
complete(font);
});
}
break;
case kCTFontDescriptorMatchingDownloading:{//下載進度
if (progress) {
dispatch_async(dispatch_get_main_queue(), ^{
progress(progressValue);
});
}
}
break;
case kCTFontDescriptorMatchingDidFailWithError:{//下載失敗
NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];
if (!error) {
error = [NSError errorWithDomain:@"ERROR MESSAGE IS NOT AVAILABLE" code:102 userInfo:nil];
}
errorDuringDownload = YES;
if (failure) {
failure(error);
}
}
break;
default:
break;
}
return (bool)YES;
});
}
- 使用字體時和平時一樣, 這里的
fontName
就是剛才下載的fontName
UIFont *font = [UIFont fontWithName:fontName size:18];
self.lab.font = font;
-
那么如何查看我可以下載哪些字體,以及下載的字體具體叫什么名字呢
其實iOS上的字體和macOS上的字體是通用的,并且字體的版權也是一致的,macOS系統(tǒng)上自帶的字體iOS上都能用.
所以只要查看macOS上的字體就可以了.
打開macOS,找到系統(tǒng)自帶的字體程序
6C2E4A89-E2B9-4CE3-B2EC-02578E020531.jpeg
打開來后是這個樣子的,左側顯示字體的名稱, 右測紅框中顯示的就是FontName
image.png
有個注意點,就是app加載過字體后,重新啟動可能發(fā)現(xiàn)字體沒有了,其實字體不是沒有,而是沒有加載進app,系統(tǒng)雖然下載好了,但是并沒有加載進來, 所以建議在AppDelegate啟動后再調(diào)一次下載字體的函數(shù),讓字體從系統(tǒng)加載到app中.
2.方案二,app動態(tài)下載字體文件到沙盒,再從沙盒加載. 字體文件是一個后綴為ttf的文件.比如這個.
image.png
網(wǎng)絡下載就用AFNetworking之類的框架, 我自己是用的YTKNetwork,就像下載文件到本地一樣,把字體文件下載到沙盒中.
之后就是加載字體
if ([fontReq existFontName]) {
NSLog(@"字體已存在:%@",fontReq.fontName);
NSString * fontPath = [NSString stringWithFormat:@"%@/%@",Rubick_Document, fontReq.fontName];
;
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
CGFontRef customfont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
NSString *fontName = (__bridge NSString *)CGFontCopyFullName(customfont);
CFErrorRef error;
CTFontManagerRegisterGraphicsFont(customfont, &error);
if (error){
// 為了可以重復注冊
CTFontManagerUnregisterGraphicsFont(customfont, &error);
CTFontManagerRegisterGraphicsFont(customfont, &error);
}
CGFontRelease(customfont);
UIFont *font = [UIFont fontWithName:fontName size:18];
//給label設置字體
self.lab.font = font;
return;
}
注意, 這里的fontName可能和你想的不太一樣
image.png
END