类似的文字方法比较
在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