本章介绍一些常见的文本布局操作,并说明如何使用核心文本执行这些操作。本章包括以下代码清单操作:
- 列出一段
- 简单文本标签
- 柱状布局
- 手动断线
- 应用段落样式
- 在非矩形区域显示文本
列出一段
排版中最常见的操作之一是在任意大小的矩形区域内排版多行段落。核心文本使这个操作变得简单,只需要几行核心文本特定的代码。要布局段落,需要绘制图形上下文、提供文本布局区域的矩形路径以及属性字符串。本例中的大多数代码都是创建和初始化上下文、路径和字符串所必需的。完成后,核心文本只需要三行代码即可完成布局。
清单2-1中的代码显示了段落的布局。此代码可以驻留在UIView子类(OSX中的NSView子类)的drawRect:方法中。
// Initialize a graphics context in iOS.
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the context coordinates, in iOS only.
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Initializing a graphic context in OS X is different:
// CGContextRef context =
// (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
// Set the text matrix.
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
// Create a path which bounds the area where you will be drawing text.
// The path need not be rectangular.
CGMutablePathRef path = CGPathCreateMutable();
// In this simple example, initialize a rectangular path.
CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0);
CGPathAddRect(path, NULL, bounds );
// Initialize a string.
CFStringRef textString = CFSTR("Hello, World! I know nothing in the world that has as much power as a word. Sometimes I write one, and I look at it, until it begins to shine.");
// Create a mutable attributed string with a max length of 0.
// The max length is a hint as to how much internal storage to reserve.
// 0 means no hint.
CFMutableAttributedStringRef attrString =
CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
// Copy the textString into the newly created attrString
CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0),
textString);
// Create a color that will be added as an attribute to the attrString.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {
1.0, 0.0, 0.0, 0.8 };
CGColorRef red = CGColorCreate(rgbColorSpace, components);
CGColorSpaceRelease(rgbColorSpace);
// Set the color of the first 12 chars to red.
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12),
kCTForegroundColorAttributeName, red);
// Create the framesetter with the attributed string.
CTFramesetterRef framesetter =
CTFramesetterCreateWithAttributedString(attrString);
CFRelease(attrString);
// Create a frame.
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(0, 0), path, NULL);
// Draw the specified frame in the given context.
CTFrameDraw(frame, context);
// Release the objects we used.
CFRelease(frame);
CFRelease(path);
CFRelease(framesetter);
简单文本标签
另一种常见的排版操作是绘制一行文本,用作用户界面元素的标签。在核心文本中,这只需要两行代码:一行用CFAttributedString创建line对象,另一行将线条绘制到图形上下文中。
清单2-2显示了如何在UIView或NSView子类的drawRect:方法中实现这一点。该清单省略了纯文本字符串、字体和图形上下文的初始化,以及本文档中其他清单中显示的操作。它展示了如何创建属性字典并使用它创建属性字符串。(字体创建显示在创建字体描述符和从字体描述符创建字体中。)
CFStringRef string; CTFontRef font; CGContextRef context;
// Initialize the string, font, and context
CFStringRef keys[] = {
kCTFontAttributeName };
CFTypeRef values[] = {
font };
CFDictionaryRef attributes =
CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys,
(const void**)&values, sizeof(keys) / sizeof(keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFAttributedStringRef attrString =
CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
CFRelease(string);
CFRelease(attributes);
CTLineRef line = CTLineCreateWithAttributedString(attrString);
// Set text position and draw the line into the graphics context
CGContextSetTextPosition(context,