说明
在ios开发中,我们经常需要根据UI来添加不同的字体,但是一个字体库少说也有10M以上,如果将字体库添加到代码中,将会增加app的大小,这显然是不明智的。
通过动态下载字体的API可以动态的向iOS 10系统添加字体文件,这些字体文件都是直接下载到系统的目录中,所以不会增加应用的大小。
字体列表
我们需要先找到字体的名字,在字体册中对应的PostScript名称
苹果官方demo下载地址
<pre>
// 判断是该字体否下载
- (BOOL)isDownloadFont:(NSString )fontName {
UIFont aFont = [UIFont fontWithName:fontName size:12.];
if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) {
return YES;
}
return NO;
}
-
(void)asynchronouslySetFontName:(NSString *)fontName
{
if ([self isDownloadFont:fontName]) {
return;
}
//用字体的PostScript名字创建一个字典
NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];//创建一个字体描述对象 CTFontDescriptorRef
CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);//将字体描述对象放到可变数组中
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) {
double progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] doubleValue];if (state == kCTFontDescriptorMatchingDidBegin) { NSLog(@" 字体已经匹配 "); } else if (state == kCTFontDescriptorMatchingDidFinish) { if (!errorDuringDownload) { NSLog(@" 字体 %@ 下载完成 ", fontName); } } else if (state == kCTFontDescriptorMatchingWillBeginDownloading) { NSLog(@" 字体开始下载 "); } else if (state == kCTFontDescriptorMatchingDidFinishDownloading) { NSLog(@" 字体下载完成 "); dispatch_async( dispatch_get_main_queue(), ^ { // 可以在这里修改 UI 控件的字体 }); } else if (state == kCTFontDescriptorMatchingDownloading) { NSLog(@" 下载进度 %.0f%% ", progressValue); } else if (state == kCTFontDescriptorMatchingDidFailWithError) { NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError]; NSString * errorMessage = nil; if (error != nil) { errorMessage = [error description]; } else { errorMessage = @"ERROR MESSAGE IS NOT AVAILABLE!"; } // 设置标志 errorDuringDownload = YES; NSLog(@"下载错误: %@", errorMessage); } return (bool)YES;
});
}
</pre>