通常,我们使用字体 都是系统默认的字体. 有时候 从阅读体验,美观度 设计师都会考虑用一些 更高大尚的字体. 系统字体库 给英文 各种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