iOS开发中涉及的字体问题
iOS中常见3种方法来控制字体,下面根据我在网上学习总结的内容发布(已完美避过所有坑,iOS8.4)
一.系统默认的设置字体方法(只对英文和数字生效的方法)
1.系统默认提供的字体主要是指UIFont中提供的字体,其使用代码为:
_label.font = [UIFont fontWithName:@"Marion" size:20.0f];
2.或者是通过字体详细字典对字体属性进行设置
/*
UIFontDescriptorFamilyAttribute:设置字体家族名
UIFontDescriptorNameAttribute :设置字体的字体名
UIFontDescriptorSizeAttribute :设置字体尺寸
UIFontDescriptorMatrixAttribute:设置字体形变
*/
//创建描述字典
NSDictionary *fontDict = @{UIFontDescriptorFamilyAttribute:@"Marion",UIFontDescriptorNameAttribute:@"Marion-Regular",UIFontDescriptorSizeAttribute:@20.0f,UIFontDescriptorMatrixAttribute:[NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(M_1_PI*1.5)]};
//创建字体描述对象
UIFontDescriptor *attributeFontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:fontDict];
//设置字体
_label.font = [UIFont fontWithDescriptor:attributeFontDescriptor size:0.0];
其中的字体家族名和字体名可以通过以下方法获取
NSLog(@"%@",[UIFont familyNames]);
以上两种方法均可以为label设置字体,但是全部是只针对英文数字,对中文无效。要想改变中文字体还需要使用后面两种办法
二.将字体包直接打入工程,内嵌字体(对中英数字有效)
现在网上不管是windows字体,还是Android字体只要是ttf格式的,或者是苹果提供的ttc、otf格式,一般iOS程序都支持内嵌
1.认识字体册
MAC -> Launchpad -> 其他 -> 字体册

2.打开字体册后可以看到有各种中英文字体,可点击各种按钮试看功能,当前我们需要设置中文,如下图所示,注意红线部分

3.特别要注意这个PostScript名称,这个名称是我们在动态下载字体以及程序里设置Label字体时所要填写的字体真实名称,而非一会要提取的字体文件名称
4.右键字体,选择当前字体文件,如果字体尚未下载则先添加字体。拖入Xcode工程中,注意勾选复制以及tagert



5.如果上面一步没有勾选复制或者targets,则会出现即使添加了字体并设置也没有任何效果的状况,这时候需要去Xcode设置中 -> Build Phases -> Copy Bundle Resources中手动添加当前的字体文件

6.在Xcode工程中的Info.plist文件中添加键Fonts provided by application,设置字体文件名为值(是字体文件名,要带上扩展名,不一定跟PostScript同名)

7.设置Label字体名为当前导入字体的PostScrip名称,即可使用
_label.font = [UIFont fontWithName:@"YuppySC-Regular" size:20.0f];
三.动态修改当前应用内字体(iOS6之后出现API,对中英数字有效)
这部分引用唐巧先生关于字体设置的博文,另外注意的是这个方法目前不完美,每次重启APP时会重新自动下载字体并加载,初步判断是因为字体下载到系统目录而非内嵌应用沙盒导致的
唐巧博客:
http://blog.devtang.com/2013/08/11/ios-asian-font-download-introduction/
苹果官方文档:
1.首先依然需要去字体册里寻找PostScript名称,这次不管是下载还是设置都要使用这个名字
2.代码示例
- (void)viewDidLoad {
[super viewDidLoad];
_label = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 300, 20)];
_label.text = @"我懂得";
[self.view addSubview:_label];
BOOL is = [self isFontDownloaded:@"HanziPenSC-W3"];
if (is)
{
_label.font = [UIFont fontWithName:@"HanziPenSC-W3" size:15.0f];
}
else
{
[self downloadFontWithAppleServers:@"HanziPenSC-W3"];
}
}
- (BOOL)isFontDownloaded:(NSString *)fontName
{
UIFont *aFont = [UIFont fontWithName:fontName size:15.0f];
if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame))
{
return YES;
}
else
{
return NO;
}
}
- (void)downloadFontWithAppleServers:(NSString *)fontName
{
//用字体的PostScript名字创建一个字典
//注意:这个方法必须导入#import <CoreText/CoreText.h>
NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName,kCTFontNameAttribute, nil];
//创建一个字体描述对象CTFontDescriptorRef
CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);
//将字体描述对象放到一个可变数组中
NSMutableArray *descArray = [NSMutableArray array];
[descArray addObject:(__bridge id)desc];
//定义一个下载错误变量
__block BOOL errorDuringDownload = NO;
//开始进行字体下载
CTFontDescriptorMatchFontDescriptorsWithProgressHandler((__bridge CFArrayRef) descArray, NULL, ^bool(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);
}
//返回主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{
_label.font = [UIFont fontWithName:fontName size:15.0f];
});
}
else if (state == kCTFontDescriptorMatchingWillBeginDownloading)
{
NSLog(@"字体开始下载");
}
else if (state == kCTFontDescriptorMatchingDownloading)
{
NSLog(@"下载进度%.0f%%",progressValue);
}
else if (state == kCTFontDescriptorMatchingDidFinishDownloading)
{
NSLog(@"字体下载完成");
}
else if (state == kCTFontDescriptorMatchingDidFailWithError)
{
NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];
NSString *errorMessage = @"";
if (error != nil)
{
errorMessage = [error description];
}
else
{
errorMessage = @"没有可用的错误信息";
}
//设置标志
errorDuringDownload = YES;
NSLog(@"下载字体时发生错误:%@",errorMessage);
}
return (BOOL)YES;
});
}
iOS开发中涉及的字体问题的更多相关文章
- css进阶 03-网页设计和开发中,关于字体的常识
03-网页设计和开发中,关于字体的常识 #前言 我周围的码农当中,有很多是技术大神,却常常被字体这种简单的东西所困扰. 这篇文章,我们来讲一讲关于字体的常识.这些常识所涉及到的问题,有很强的可操作性, ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- iOS开发中打电话发短信等功能的实现
在APP开发中,可能会涉及到打电话.发短信.发邮件等功能.比如说,通常一个产品的"关于"页面,会有开发者的联系方式,理想情况下,当用户点击该电话号码时,能够自动的帮用户拨出去,就涉 ...
- IOS开发中UI编写方式——code vs. xib vs.StoryBoard
最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关 ...
- iOS开发中调试小技巧
对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...
- 多线程在iOS开发中的应用
多线程基本概念 01 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 02 线程 2-1 基本概念 1个进程要想执行任务,必须得有线程 ...
- iOS开发中你是否遇到这些经验问题
前言 小伙伴们在开发中难免会遇到问题, 你是如何解决问题的?不妨也分享给大家!如果此文章其中的任何一条问题对大家有帮助,那么它的存在是有意义的! 反正不管怎样遇到问题就要去解决问题, 在解决问题的同时 ...
- 深入理解 iOS 开发中的锁
来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大 ...
- iOS开发中关于UIImage的知识点总结
UIImage是iOS中层级比较高的一个用来加载和绘制图像的一个类,更底层的类还有 CGImage,以及iOS5.0以后新增加的CIImage.今天我们主要聊一聊UIImage的三个属性: image ...
随机推荐
- 锤子便签的 monkeyrunner 测试脚本(转)
https://testerhome.com/topics/878 MonkeyRunner可能大家已经听过无数次了,大家在网上也看过了各种关于的它的资料了,我这里就不再过多的啰嗦它的用途了,它可以对 ...
- Linux学习 -- Shell编程 -- 字符处理命令
sort排序命令 sort [选项] 文件名 -f 忽略大小m写 -n 按数值型,默认字符串型 -r 反向 -t 指定分隔符 -k n[,m] 指定字段范围,默认行尾 eg. sort -n -t & ...
- CentOS安装VirtualBox增强工具
安装过程中出现错误: Bulding the VirtualBox Guest Additions Kernel modules failedYour system does not seem to ...
- Ubuntu 9.10+ apache2.2 +Django的配置
1.首先安装mod_python apt-get install libapache2-mod-python2.6 (Ubuntu 9.10默认安装的是python 2.6版,如果是2.5可改为 li ...
- Entity Framework 学习初级篇6--EntityClient
System.Data.EntityClient 命名空间是 实体框架的 .NET Framework 数据提供程序.EntityClient 提供程序使用存储特定的 ADO.NET 数据提供程序类和 ...
- ACL in 和 out 区别 (重要)
acl中in和out的区别 in和out是相对的,比如: A(s0)-----(s0)B(s1)--------(s1)C www.2cto.com 假设你现在想拒绝A访问C,并且假设要求 ...
- linux性能优化cpu 磁盘IO MEM
系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...
- 3个普通IO识别22个按键试验(转)
源:http://www.amobbs.com/forum.php?mod=viewthread&tid=2243715 吸取各位前辈的经验,将之前二极管用量多的问题优化一下,目前不用二极管能 ...
- Ubuntu系统如何修改主机名
1.执行命令 hostname temp_name 这样主机名就改掉了.只不过重启后名字会恢复不一定使我们想要的.机器重启后会重新去读取/etc/hostname里面存储的主机名.所以如果想永久改掉的 ...
- ural1701 Ostap and Partners
Ostap and Partners Time limit: 2.0 secondMemory limit: 64 MB Workman Ivan lost his job. Not because ...