一、概述
1.CoreText是苹果创建的一个用于文字排版的框架,可以实现文字排版、图文混排等复杂的界面效果。从iOS3.2启用。
2.一个开源工具类-OHAttributedLabel,就是使用CoreText框架实现的,能够实现一个Label中有不同的文字大小、文字颜色、字体以及链接等。
二、一般使用步骤
1.创建NSMutableAttributedString
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:contentString];
2.设置文字颜色
[attributeString addAttribute:(id)kCTForegroundColorAttributeName
value:(id)[UIColor darkGrayColor].CGColor
range:NSMakeRange(0, tempArticle.desc.length)];
2.设置字体以及大小
CTFontRef font = CTFontCreateWithName(CFSTR("Bodoni 72"), contentFontSize, NULL);
[attributeString addAttribute:(id)kCTFontAttributeName value:(id)font range:NSMakeRange(0, [attributeString length])];
CFRelease(font);
4.初始化段落首行缩进样式
CGFloat headIndent = contentFontSize * 2;
CTParagraphStyleSetting headIndentStyle;
headIndentStyle.spec = kCTParagraphStyleSpecifierFirstLineHeadIndent;
headIndentStyle.valueSize = sizeof(headIndent);
headIndentStyle.value = &headIndent;
5.初始化文字对齐方式
CTTextAlignment alignment = kCTJustifiedTextAlignment;
CTParagraphStyleSetting alignmentStyle;
alignmentStyle.spec = kCTParagraphStyleSpecifierAlignment;
alignmentStyle.valueSize = sizeof(alignment);
alignmentStyle.value = &alignment;
6.初始化行间距
CGFloat lineSpace = 12.0f;
CTParagraphStyleSetting lineSpaceStyle;
lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacing;
lineSpaceStyle.valueSize = sizeof(lineSpace);
lineSpaceStyle.value = &lineSpace;
7.初始化段间距
CGFloat paragraphSpace = 18;
CTParagraphStyleSetting paragraphSpaceStyle;
paragraphSpaceStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing;
paragraphSpaceStyle.valueSize = sizeof(paragraphSpace);
paragraphSpaceStyle.value = ¶graphSpace;
8.将段落属性设置到NSMutableAttributedString
CTParagraphStyleSetting settings[4] = {headIndentStyle,alignmentStyle,lineSpaceStyle,paragraphSpaceStyle};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate((const CTParagraphStyleSetting*)&settings,4);
[attributeString addAttribute:(id)kCTParagraphStyleAttributeName
value:(id)paragraphStyle range:NSMakeRange(0, [attributeString length])];
CFRelease(paragraphStyle);
9.创建CTFramesetterRef
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributeString);
10.绘制之前,翻转绘图坐标系
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
11.按照区域进行绘制
CFIndex startIndex = 0;
NSInteger pathCount = 0;
while (YES) {
//构建绘图区域
CGMutablePathRef columnPath = CGPathCreateMutable();
CGPathAddRect(columnPath, NULL,
CGRectMake(20 + (pathCount%columnNum) * ((768-(columnNum+1)*20)/columnNum + 20), 50, (768-(columnNum+1)*20)/columnNum, 904));
//构建内容窗体
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(startIndex,0), columnPath, NULL);
//绘制内容窗体
CTFrameDraw(frame, context);
//计算当前显示结束位置的字符索引
CFRange currRange = CTFrameGetVisibleStringRange(frame);
startIndex = startIndex + currRange.length;
//释放
CGPathRelease(columnPath);
CFRelease(frame);
//计数增加
pathCount++;
//结束
if (startIndex == [attributeString length]) {
break;
}
}
12.按照行进行绘制
CFIndex start = 0;
while (YES) {
//判断是否绘制完毕
if (start == attributeString.length) {
break;
}
//根据内容、开始索引位置和绘制区域的宽度,返回推荐的换行位置索引
CFIndex count = CTTypesetterSuggestLineBreak(frameSetter, start, pageWidth);
//创建一个新行
CTLineRef line = CTTypesetterCreateLine(frameSetter, CFRangeMake(start, count));
//获取新行的排版属性
CGFloat ascent;
CGFloat descent;
CGFloat leading;
CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
//计算新行的Y值
imageY = imageY - lineSpace - ascent - descent - leading;
//绘制行
CGContextSetTextPosition(currContext, 0.0f, imageY);
CTLineDraw(line, currContext);
//释放行对象
CFRelease(line);
//更改当前绘制的位置索引
start += count;
}