面试题答案
一键面试实现主要步骤:
- 创建
NSAttributedString
:将纯文本转换为带有属性的字符串,设置首行缩进和行间距等属性。 - 创建
CTFramesetter
:使用NSAttributedString
创建CTFramesetter
对象。 - 定义绘制区域:确定文本要显示的区域大小。
- 创建
CTFrame
:根据CTFramesetter
和绘制区域创建CTFrame
对象。 - 绘制文本:在视图的
drawRect:
方法中使用CTFrame
进行绘制。
关键代码片段:
#import <CoreText/CoreText.h>
#import <UIKit/UIKit.h>
@interface TextViewController : UIViewController
@end
@implementation TextViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 纯文本
NSString *plainText = @"这是一段需要排版的纯文本。";
// 创建NSMutableAttributedString
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:plainText];
// 设置首行缩进
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.firstLineHeadIndent = 2 * 12; // 假设一个字符12点
paragraphStyle.lineSpacing = 12; // 1.5倍行距假设字号16,1.5倍行距为12
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedString.length)];
// 创建CTFramesetter
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString);
// 定义绘制区域
CGRect rect = CGRectMake(50, 50, self.view.bounds.size.width - 100, self.view.bounds.size.height - 100);
CGPathRef path = CGPathCreateWithRect(rect, NULL);
// 创建CTFrame
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
// 释放相关对象
CFRelease(framesetter);
CFRelease(path);
// 存储CTFrame以便在drawRect中使用
self.frame = frame;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.view.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CTFrameDraw((__bridge CTFrameRef)self.frame, context);
CFRelease((__bridge CFTypeRef)self.frame);
}
@end
在上述代码中:
viewDidLoad
方法里设置文本属性并创建CTFrame
。drawRect:
方法负责将CTFrame
绘制到视图上。注意坐标转换,因为Core Text坐标系与UIKit坐标系方向不同。