在iOS的开发中经常遇到需要使用一些自定义的字体文件,比如仿宋_GB2312、方正小标宋_GBK等。之前我们为了使用这些自定义的字体,在应用的资源包中放入这些字体文件。因为字体文件通常比较大,有的一个字库就达到10M以上(拿方正小标宋_GBK这个字库来说就有13M之多),这样打包后的ipa文件的体积就可能会变得很大,对于只有个别的模块需要特殊的字体样式的应用来说很不划算,那么在iOS6.0以后苹果就开放了动态加载字体的权限。下面就iOS中使用字体的这两种方式进行介绍。

使用静态字体

1、将字体文件拷贝到项目工程中,在Info.plist文件中添加Fonts provided by application的配置项,其中每一个Item对应的是字体文件的名称,如DS-DIGI.TTF。

2、使用时直接按照如下方式即可:

_textLabel1.font = [UIFont fontWithName:@"DS-Digital" size:40];

效果如下:

3、其他说明:

+ (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;这个方法中需要指定的fontName不是前面设置的字体文件的文件名,而应该是字体的名称,如何获取字体的名称可以通过如下方式:

(1)打印出当前所有可用的字体,查找对应的字体名称

- (void)printAllFonts {NSArray *fontFamilies = [UIFont familyNames];for (NSString *fontFamily in fontFamilies) {NSArray *fontNames = [UIFont fontNamesForFamilyName:fontFamily];NSLog (@"%@: %@", fontFamily, fontNames);}}

(2)通过Mac自带的字体册查看字体的名称

直接双击字体即可打开字体册,如果系统没有安装该字体按照要求安装即可,然后可以在字体的详细信息中找到对应的字体的名称:

使用动态字体

1、动态下载自定义的字体

在网易新闻iOS客户端中可以使用自定义的字体,对于未下载的字体可先下载然后安装下次就能自动设置为该字体,效果如下:

下面就该功能简单介绍实现的步骤

(1)下载指定的字体文件到本地

第一次进入该页面会自动到服务器上获取可使用的字体的列表,示例如下:

[{
"fontTitle": "华康圆体",
"regularName": "DFYuanW3-GB",
"boldName": "DFYuanW5-GB",
"author": "华康科技",
"date": "2012-10-11",
"fileUrl": "http://xxxx/font/dfgb_y.zip",
"fileSize": "3.3MB",
"previewUrl": "http://yyyy/font/ios_yuanti.png"
}]

上面的内容指明了字体的名称,下载地址等信息,从上面的内容可以看出下载回来的字体文件是一个zip压缩包,再使用前还需要进行解压处理。

1)下载字体文件

- (NSString *)downloadZipFile:(NSString *)fileUrl toPath:(NSString *)path {NSError *error = nil;NSURL *url = [NSURL URLWithString:fileUrl];NSString *fileName = [url lastPathComponent];NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];if(!error) {NSString *zipPath = [path stringByAppendingPathComponent:fileName];[data writeToFile:zipPath options:0 error:&error];if(!error) {return zipPath;}}return nil;
}

2)解压zip压缩包

iOS中解压zip压缩文件非常方便,使用ZipArchive这个开源项目按照如下的方式即可快速解压zip文件。

- (NSString *)expandZipFile:(NSString *)src toPath:(NSString *)desc {ZipArchive *za = [[ZipArchive alloc] init];if ([za UnzipOpenFile:src]) {BOOL ret = [za UnzipFileTo:desc overWrite:YES];//解压文件if(ret){NSString *zipName = [src lastPathComponent];//获取zip文件的文件名[[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];//删除zip压缩包zipName = [zipName substringToIndex:[zipName rangeOfString:@".zip"].location];//获取解压到的文件夹return [self.downloadPath stringByAppendingPathComponent:zipName];}}return nil;
}

ZipArchive项目地址:https://github.com/mattconnolly/ZipArchive

(2)注册指定路径下的字体文件

下载回来的字体文件如果不做处理是不能直接使用的,使用前需要先注册然后才能使用,注册方式如下:

需要先引入#import <CoreText/CoreText.h>,CoreText框架。
- (void)registerFont:(NSString *)fontPath {NSData *dynamicFontData = [NSData dataWithContentsOfFile:fontPath];if (!dynamicFontData){return;}CFErrorRef error;CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((__bridge CFDataRef)dynamicFontData);CGFontRef font = CGFontCreateWithDataProvider(providerRef);if (! CTFontManagerRegisterGraphicsFont(font, &error)){//注册失败CFStringRef errorDescription = CFErrorCopyDescription(error);NSLog(@"Failed to load font: %@", errorDescription);CFRelease(errorDescription);}CFRelease(font);CFRelease(providerRef);
}// 注册方式2,使用URLNSString *imgFilePath = [filePath path];NSURL *fontUrl = [NSURL fileURLWithPath:imgFilePath];CGDataProviderRef fontDataProvider =  CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);//the next line is relevant part[UIFont familyNames];CGDataProviderRelease(fontDataProvider);CTFontManagerRegisterGraphicsFont(fontRef, NULL);NSString *fontName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));label.font = [UIFont fontWithName:fontName size:24];

在调用注册CTFontManagerRegisterGraphicsFont前最好调下[UIFont familyNames];苹果内部的一个bug.

ios - CGFontCreateWithDataProvider hangs in airplane mode - Stack Overflow

(3)判断字体是否加载

在使用字体文件前最好是先判断字体是否已经被加载过了,判断方式如下:

- (BOOL)isFontDownloaded:(NSString *)fontName {UIFont* aFont = [UIFont fontWithName:fontName size:12.0];BOOL isDownloaded = (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame));return isDownloaded;
}

(4)其他说明

经测试注册过的字体在应用关闭后下次开启应用,判断字体是否加载时返回为NO,为了保证正常使用需要每次启动应用的时候先遍历一遍字体文件夹将里面的字体文件都再次注册一遍即可。参考代码如下:

    //注册fonts目录下面的所有字体文件NSArray *ary = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.downloadPath error:nil];for (NSString *p1 in ary) {NSString *t1 = [self.downloadPath stringByAppendingPathComponent:p1];NSArray *ary1 = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:t1 error:nil];for (NSString *p1 in ary1) {NSString *t2 = [t1 stringByAppendingPathComponent:p1];if([t2 rangeOfString:@".ttf"].location != NSNotFound) {[self registerFont:t2];}}}

2、动态下载苹果提供的字体

大多数的中文字体是有版权的,在应用中加入特殊中文字体还需要处理相应的版权问题。从iOS6开始,苹果就支持动态下载中文字体到系统中。

(1)苹果支持下载的字体列表

1)iOS6字体列表:http://support.apple.com/zh-cn/HT202599

2)iOS7字体列表:http://support.apple.com/zh-cn/HT5878

(2)官方提供的示例代码

访问https://developer.apple.com/library/ios/samplecode/DownloadFont/Introduction/Intro.html下载示例程序。针对示例程序简单介绍如下:

1)判断字体是否已经被下载过

UIFont* aFont = [UIFont fontWithName:fontName size:12.];if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) {
// 字体已经被加载过,可以直接使用
return;}

2)下载字体

    // 根据字体的PostScript名称构建下载字体所需的参数://使用字体的PostScript名称构建一个字典NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];//根据上面的字典创建一个字体描述对象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) {dispatch_async( dispatch_get_main_queue(), ^ {//开始匹配NSLog(@"Begin Matching");});} else if (state == kCTFontDescriptorMatchingDidFinish) {dispatch_async( dispatch_get_main_queue(), ^ {if (!errorDuringDownload) {//字体下载完成NSLog(@"%@ downloaded", fontName);//TODO:在此修改UI控件的字体样式}});} else if (state == kCTFontDescriptorMatchingWillBeginDownloading) {//开始下载NSLog(@"Begin Downloading");dispatch_async( dispatch_get_main_queue(), ^ {//TODO:在此显示下载进度提示});} else if (state == kCTFontDescriptorMatchingDidFinishDownloading) {//下载完成NSLog(@"Finish downloading");dispatch_async( dispatch_get_main_queue(), ^ {//TODO:在此修改UI控件的字体样式,隐藏下载进度提示});} else if (state == kCTFontDescriptorMatchingDownloading) {//正在下载NSLog(@"Downloading %.0f%% complete", progressValue);dispatch_async( dispatch_get_main_queue(), ^ {//TODO:在此修改下载进度条的数值});} else if (state == kCTFontDescriptorMatchingDidFailWithError) {//下载遇到错误,获取错误信息NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];NSLog(@"%@", [error localizedDescription]);//设置下载错误标志errorDuringDownload = YES;}return YES;});

(3)说明

1)使用动态下载中文字体的API可以动态地向iOS系统中添加字体文件,这些字体文件都是下载到系统的目录中(目录是/private/var/mobile/Library/Assets/com_apple_MobileAsset_Font/),所以并不会造成应用体积的增加,而且可以在多个应用中共享。

2)如何获取字体的PostScript和FontName?可以通过Mac系统自带的字体册来查看。具体请参考前面的步骤。

iOS中使用自定义字体, 动态下载字体相关推荐

  1. iOS字体 动态下载系统提供的多种中文字体

    一.场景.当前众多APP使用情况 在WWDC的内容公开之前,大家都以为iOS系统里面只有一种中文字体.为了达到更好的字体效果,有些应用在自己的应用资源包中加入了字体文件.但自己打包字体文件比较麻烦,原 ...

  2. iOS 6:动态下载字体

    2019独角兽企业重金招聘Python工程师标准>>> iOS 6:字体列表 了解 iOS 6 中所使用的字体. iOS 6 随附安装了下列字体: Academy Engraved ...

  3. iOS 中如何添加应用自己的字体,使用萍方体

    1.第一步找到你想用的字体的 ttf 格式.加入到你的工程的resouce目录下. 2.在工程的plist中AddRow,"Fonts provided by application&quo ...

  4. iOS 中如何添加应用自己的字体

    今天蛋疼,突然想用下漂亮的字体,就稍微用研究了一下这个用法,很简单,就三步吧 1.第一步找到你想用的字体的 ttf 格式.加入到你的工程的resouce目录下. 2.在工程的plist中AddRow, ...

  5. IOS中Cell自定义

    我们经常用到Cell,在这个地方我们利用cell是来盛放一个对象,在前面我们也介绍了从plist文件中获取到对象,并且存储到一个数组中,在这个程序中主要来说从Cell中获取到对象之后,我们要将数据对象 ...

  6. Android中使用可下载字体

    可下载字体简介 在Android 8.0(API level 26)和Android Support库26开始提供了从字体提供程序下载字体的API接口,用以替代将字体绑定打包到APK文件中,或者让AP ...

  7. php文字红色代码,IOS_IOS中一段文字设置多种字体颜色代码,给定range和需要设置的颜色, - phpStudy...

    IOS中一段文字设置多种字体颜色代码 给定range和需要设置的颜色,就可以给一段文字设置多种不同的字体颜色,使用方法如下: [self fuwenbenLabel:contentLabel Font ...

  8. figma:使用mac上的字体 | 转换ttc字体文件

    figma:使用mac上的字体 | 转换ttc字体文件 现在的主力系统是Mac,偶尔会切到Windows,打开 figma 时发现缺少字体,原来里面有mac上才有的字体,之前都是切回mac重新编辑,但 ...

  9. ubuntu vscode 终端字体设置(字体间隔过大)

    ubuntu vscode 终端字体设置(字体间隔过大) 1 问题 2 原因 3 处理 3.1 查看系统字体 3.2 设置系统预置字体 3.3 设置自定义字体 1 问题 ubuntu 18.04 系统 ...

  10. 网络服务器打印系统字体发生改变,管理字体

    管理字体 如果使用激光打印机,则可能需要安装和维护 PostScript 字体.对于许多打印机来说,字体都是在打印机安装过程中设置的. PostScript 字体以轮廓形式存储在打印机上,或与打印机进 ...

最新文章

  1. 最实用的Office使用技巧
  2. python红色_python把红玫瑰变成蓝色女巫,将,红色,转化,为,蓝色妖姬
  3. flutter版本控制工具 `FVM`
  4. hdoj1242(dfs 剪枝 解法)
  5. 《TCP/IP详解》笔记----第四章 ARP协议
  6. DBUtils学习笔记
  7. keycloak学习
  8. 微软 azure_Microsoft Azure管理员方案相关的面试问题与解答
  9. python老师 招聘_崩了,Python玩大了! 程序员:牛,不可惜!
  10. Java集合类的整理
  11. 相机拍照功能之权限和Android版本问题
  12. eclipse svn SSL 错误
  13. 安庆集团-冲刺日志(第八天)
  14. (Animator详解一)mixamo动画导入Unity的一些配置
  15. 将Unity地形以Wavefront Obj格式导出
  16. SYSCALL_DEFINEx宏源码解析
  17. Web3+品牌的大杀器:DAO如何实现对传统品牌彻底的降维打击
  18. 解读ConnectBot-1 telnet、ssh常识
  19. python基础知识下载_python基础知识(实用)
  20. 紫罗兰永恒花园rust简谱_【Sincerely】简谱 自制 高清

热门文章

  1. Linux镜像克隆网卡流量
  2. 数学建模c语言知识,数学建模方法总结
  3. MyEclipse创建Java项目
  4. 两台redhat7虚拟机配置ssh免密访问
  5. Linux Redhat7 防火墙关闭/开启查看
  6. python建模与仿真控制系统_控制系统的建模与仿真
  7. 盘点俄罗斯大神写的几款软件,你用过几个?最后1个是我的童年
  8. 使用Scapy进行网络扫描
  9. 注册测绘师划出后的分析与思考
  10. python读取txt文件数据并存到list中