通常,我们使用字体 都是系统默认的字体. 有时候 从阅读体验,美观度 设计师都会考虑用一些 更高大尚的字体. 系统字体库 给英文 各种style的发挥空间很大,但是 中文则不然.
但是苹果 给使用中文的字体的开发者提供了 动态下载字体库的福利,这个真是好,并且下载到/private/var/mobile/Library/Assets/com_apple_MobileAsset_Font/ 这样不会增加app本身的大小. 不失为一种好的选择.
前提: 你首先 要知道 你要使用的字体的官方名字, 用这个名字 当索引下载.
官方竟然有文档和demo 真是方便的不要不要的:
https://developer.apple.com/library/ios/samplecode/DownloadFont/Listings/DownloadFont_ViewController_m.html
操作基本步骤
1. 首先判断 是否有这种字体 无则用默认的
(如果 要使用一些 iOS8,iOS9才有的字体 一定要考虑低版本用户的情况,会闪退,在 font 类别里面也要做预判断,没有这个字体 就用默认的呗)
+ (UIFont *)normalHfFontWithSize: (CGFloat)fontSize { return [UIFont isFontDownloaded:@"FZLTXHK--GBK1-0"] ? [UIFont fontWithName:@"FZLTXHK--GBK1-0" size:fontSize] : [UIFont systemFontWithSize:fontSize]; } + (BOOL)isFontDownloaded:(NSString *)fontName { UIFont* aFont = [UIFont fontWithName:fontName size:12.0]; if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) { return YES; } else { return NO; } }
2. 我的下载策略 是 打开应用 就在父线程里面 处理 需要的字体下载等事宜 , 也有人 是用再下载 ,看需求吧
Reachability *r = [Reachability reachabilityForInternetConnection]; [r startNotifier]; NetworkStatus netStatus = [r currentReachabilityStatus]; NSArray *fonts = @[@"FZLTZHK--GBK1-0",@"FZLTXHK--GBK1-0"]; for (NSString *font in fonts) { NSString *isFontAvailable = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"FontDownloaded%@",font]]; if ((netStatus == ReachableViaWiFi && ![isFontAvailable isEqualToString:font]) || [isFontAvailable isEqualToString:font]) { [UIFont downloadFont:font]; } }
+ (void)downloadFont:(NSString *)fontName { UIFont* aFont = [UIFont fontWithName:fontName size:12.]; // If the font is already downloaded if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) { // Go ahead and display the sample text. return; } // Create a dictionary with the font's PostScript name.
NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil]; // Create a new font descriptor reference from the attributes dictionary. CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs); // 将字体描述对象放到一个NSMutableArray中
NSMutableArray *descs = [NSMutableArray arrayWithCapacity:0]; [descs addObject:(__bridge id)desc]; CFRelease(desc); __block BOOL errorDuringDownload = NO; // Start processing the font descriptor.. // This function returns immediately, but can potentially take long time to process. // The progress is notified via the callback block of CTFontDescriptorProgressHandler type. // See CTFontDescriptor.h for the list of progress states and keys for progressParameter dictionary. CTFontDescriptorMatchFontDescriptorsWithProgressHandler( (__bridge CFArrayRef)descs, NULL, ^(CTFontDescriptorMatchingState state, CFDictionaryRef progressParameter) { NSString *errorMessage; DLog( @"state %d - %@", state, progressParameter); // double progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] doubleValue]; if (state == kCTFontDescriptorMatchingDidBegin) { dispatch_async( dispatch_get_main_queue(), ^ { DLog(@"Begin Matching"); }); } else if (state == kCTFontDescriptorMatchingDidFinish) { dispatch_async( dispatch_get_main_queue(), ^ { // Log the font URL in the console CTFontRef fontRef = CTFontCreateWithName((__bridge CFStringRef)fontName, 0., NULL); CFStringRef fontURL = CTFontCopyAttribute(fontRef, kCTFontURLAttribute); DLog(@"%@", (__bridge NSURL*)(fontURL)); CFRelease(fontURL); CFRelease(fontRef); if (!errorDuringDownload) { [[NSUserDefaults standardUserDefaults] setObject:fontName forKey:[NSString stringWithFormat:@"FontDownloaded%@",fontName]]; [[NSUserDefaults standardUserDefaults] synchronize]; DLog(@"%@ downloaded", fontName); } }); } else if (state == kCTFontDescriptorMatchingWillBeginDownloading) { dispatch_async( dispatch_get_main_queue(), ^ { DLog(@"Begin Downloading"); }); } else if (state == kCTFontDescriptorMatchingDidFinishDownloading) { dispatch_async( dispatch_get_main_queue(), ^ { DLog(@"Finish downloading");// 可以在这里修改UI控件的字体
}); } else if (state == kCTFontDescriptorMatchingDownloading) { dispatch_async( dispatch_get_main_queue(), ^ { //DLog(@"Downloading %.0f%% complete", progressValue); }); } else if (state == kCTFontDescriptorMatchingDidFailWithError) { // An error has occurred. // Get the error message NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError]; if (error != nil) { errorMessage = [error description]; } else { errorMessage = @"ERROR MESSAGE IS NOT AVAILABLE!"; } // Set our flag设置标志
errorDuringDownload = YES; dispatch_async( dispatch_get_main_queue(), ^ { DLog(@"Download error: %@", errorMessage); }); } return (bool)YES; }); }
妥妥的 满足使用动态下载的字体需求
备注:
其他方法还有 使用字体资源文件(尾缀为.ttf或otf格式文件),上网上搜吧 讲解 一堆 .
但是这里存在的问题 1 需要把这个 .ttf文件 target到工程 不像 动态下载不增加 应用本身的大小 的特点
其次是 如果没有处理版权问题,这个就大发了 是吧...
看需求 正确使用 恰当的方法解决问题吧
参考:
http://www.awnlab.com/archives/2658.html