CoreText文字排版

来源:互联网 发布:周润发 让子弹飞 知乎 编辑:程序博客网 时间:2024/06/04 17:53

类似的文字方法比较

在iOS中,我们可以使用UIKit和CoreGraphics/Quartz都可以绘制文字和图片,UIKit可以提供简单的操作文本的方法,但是你无法修改文本的颜色和其中的单词,而如果使用CoreGraphics/Quartz,几乎允许你做任何系统允许做的事情,但是你必须为每个自行计算位置,并且画在屏幕上,比较麻烦,而CoreText结合了这两者,你可以完全控制位置、布局、类似文本大小和颜色这样的属性,而 Core Text 将帮你完善其它的东西——类似文本换行、字体呈现等等。

初探CoreText

这里写图片描述

上图是我在网上找的CoreText绘制的流程,首先你需要创建一个NSAttributedString,并且通过CTFramesetterCreateWithAttributedString来生成一个CTFramesetter的结构。

CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);

然后我们要创建一个CGPath ,这个用来指定绘制的文本的范围,CTFramesetter通过这个范围来创建一个用于绘制的帧CTFrame,当你创建帧时,您指定一个用于此帧矩形内的子文本范围。Core Text 为每行文本自动创建一个 CTLine (注意这里) 与并创建多个 CTRun 文本分段,每个 CTRun 内的文本有着同样的格式,CTRun代表这文本的一个属性,比如有个CTRun代表粗体,有的代表红色字体等等,正是因为有CTRun,所以你可以精确的控制字距,连字,宽度,高度等更多属性,在把它画到上下文中

CGMutablePathRef path = CGPathCreateMutable();    CGRect bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);    CGPathAddRect(path, NULL, bounds);CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter,CFRangeMake(0, 0), path, NULL);CTFrameDraw(ctFrame, context);

你在这里可能会想,我都没有设置这些属性,那生成的CTRun难道是空的吗?往上看,你创建CTFramesetter的时候不是利用了NSAttributedString了吗?我们在之前通过给属性字符串设置属性(后面创建的CTRun是通过这些属性自动生成的),
比如setAttributes:range,但在实践中这是一种笨拙的处理方式(除非你费力地编写大量代码),因此,为了更简单地处理问题,我们将创建一个简单的文本标记解析器,它允许我们在内容中使用简单的标签设置格式。

其实使用coretext来排版只是通过CTRun把该显示图片的地方给预留下来了,真正的显示图片还是要通过coreGraphics,当要显示图片的时候,我们通过遍历所有的CTRun,通过下面的方法

NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);

找到当初预留的那个NSAttributed的那块地方,然后通过

CGContextDrawImage(context, imageDrawRect, image.CGImage);

把图片画上去。当 Core Text 获知一个拥有 CTRunDelegate 委托的 CTRun 时,它会询问委托对象 —— 我需要为这些块数据保留多少宽度和高度?这样你就在文本中建造了一个洞,然后你把图像在那里绘制出来。

CTRunDelegateCallbacks imageCallbacks;    imageCallbacks.version = kCTRunDelegateVersion1;    imageCallbacks.dealloc = RunDelegateDeallocCallback;    imageCallbacks.getAscent = RunDelegateGetAscentCallback;    imageCallbacks.getDescent = RunDelegateGetDescentCallback;    imageCallbacks.getWidth = RunDelegateGetWidthCallback;    //第二个参数作为鉴别是哪个run的标志    CTRunDelegateRef runDelegate = CTRunDelegateCreate(&imageCallbacks, taobaoImageName);[imageAttributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(id)runDelegate range:NSMakeRange(0, 1)];//指定给图片留的空地的位置

下面是我在网上找的CoreText的实例程序
链接: http://pan.baidu.com/s/1pJ039s3 密码: ewxn

0 0