Core Text浅析

( 工作两年以来,除了最初的由零开始学习iOS编程外,后来的模式多是现用现学,以结果为导向。现在突然来了这么一遭,本人表示真心不适应。不过事儿的确是好事儿,只能慢慢适应了,毕竟我的写作水平还停留在毕设阶段。最近为了项目,接触了Core Text编程,就现学现卖一把了。)

 

一、 什么是Core Text?

Core Text是在iOS3.2、OSX10.5及以上版本中引入的文本布局及格式化引擎,设计初衷如下:

1、  完整、统一的文本布局和字体API集;

2、  高效易用;

3、  和Core Foundation、Core Graphics(Quartz)及Cocoa紧密关联;

4、  原生Unicode处理;

5、  64-bit应用程序支持;

6、  简洁、连贯且灵活的API设计;

7、  可预测的成本结构和合理分工。

总而言之,就是简单的事情简单做。

 

二、 为什么选择Core Text?

在UIKit中,我们通常使用UILabel和UITextView来显示文字,但是所有文字只能使用单一的字体,如果想改变文字颜色或者字体,它们就无能为力了。Core Graphics(Quartz)能够完成很多UIKit做不到的事,但是没有足够易用的接口。Core Text是结合并超越两者的产物,它使我们对文本布局、字体颜色大小、段落样式等等你想的到的想不到的方方面面具有完全的掌控,使用起来也非常便捷。

 

三、 如何使用Core Text?

Core Text提供了以下对象,对象名均以CT开头:

1、  CTFramesetter:使用CTTypesetter根据给定的NSAttributedString和CGPath生成CTFrame,NSAttributedString是Core Text得以完成如此多复杂效果的功臣;

2、  CTTypesetter:设置段落样式,比如换行、行间距等;

3、  CTFrame:代表一段文字,含有数个CTLine对象;

4、  CTLine:代表一行文字,含有数个glyph-run即CTRun对象;

5、  CTRun:具有相同属性的有序字形集合。glyph即字形,用来描述文字的图形形状,不同的字体或样式都有不同的字形,如图1所示。

图1                         字形展示

图2很形象直观的展现了Core Text各对象间的包含关系,是一个比较完整的Core Text对象模型。

图2                            CoreText对象模型

下面讲一下如何用程序实现简单的文本布局:

1、  初始化CGPath

CGMutablePathRef path= CGPathCreateMutable();

CGRect bounds =CGRectMake(10.0, 10.0, 200.0, 200.0);

CGPathAddRect(path,NULL, bounds);

2、  初始化NSAttributedString

CFStringRef string =CFSTR("Core Text");

CFMutableAttributedStringRefattrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);

CFAttributedStringReplaceString(attrString, CFRangeMake(0, 0), string);

此处可以添加想要的样式,字体、字形、颜色、字间距、行间距或者加个下划线神马的。

3、  生成CTFramesetter

CTFramesetterRefframesetter = CTFramesetterCreateWithAttributedString(attrString);

CTFrameRef frame =CTFramesetterCreateFrame(framesetter,CFRangeMake(0, 0), path, NULL);

然后就可以绘制了。另外,还可以结合touch事件实现其他功能,比如打开网址、播打电话等常用功能。

怎么实现图文混排呢?Core Text本身没有画图能力,但是它是一个出色的布局引擎,取巧的做法是为图像留出合适的位置,然后再自行绘图。此时会用到CTRunDelegate(如图3所示),通过设置CTRunDelegate回调方法可以获取CTRun的上下缘高度及宽度,然后设置成理想的参数为图像留白。

图3                            CTRunDelegate

 

四、 Core Text完美吗?

完美只是美丽的愿景,Core Text也不例外。在使用中,我发现了以下问题:

1、  CTFramesetterCreateFrame函数计算出的CTFrame超出了给定bounds

这个问题困扰了我几个版本了,原以为使用Core Text万无一失呢。UITextView的漏洞在于计算的是一个高度,layout时可能因为换行或其他原因临时更改了高度。Core Text又有所不同,计算得到的宽度根本就已经超出限定范围。

解决方法是使用这个函数:double CTLineGetTypographicBounds( CTLineRef line, CGFloat* ascent,CGFloat* descent, CGFloat* leading ),输入一个CTLine对象,可以得到其ascent、descent和leading值,返回值是其宽度,ascent、descent和leading三者相加即为该行高度。图片留白部分的descent和leading均为0,为了确保行间距,可以人为设置成合适的数值。图4为基本的字形术语:

图4                            字形术语

2、  字体与设定不符

以前通用的系统字体Helvetica在Core Text上居然栽了跟头,比非CoreText上绘制的要粗许多,这个问题通过设置其他字体解决了。

3、  NSDataDector检测链接耗时过多

- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block;

NSTextCheckingResult代表各种链接,时间地址电话网址自定义等。NSDataDector是一个专门配合NSTextCheckingResult检测文本是否是特定链接的类,继承于NSRegularExpression类,但是这个函数耗时过多。

解决方法是自己写网址和电话号码的正则表达式,能提速不少。

  暂时只有这么多,欢迎大家交流学习啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值