CoreText研究
参考链接
如何使用Core Text计算一段文本绘制在屏幕上之后的高度
简单绘制
直接上图

核心代码:
|
|
代码解析:
CGContextRef context = UIGraphicsGetCurrentContext();
简单说就是一个绘画的区域(context)
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);CGContextScaleCTM(context, 1.0, -1.0);
坐标系转换,简单来说平时我们理解的坐标系原点在右下角

CGContextTranslateCTM(context, 0, self.bounds.size.height);
将坐标系(0,0)移动到(0, self.bounds.size.height)位置,

CGContextScaleCTM(context, 1.0, -1.0);
将坐标系沿x翻转

这样就完美转化成我们开发时的坐标系了
CGMutablePathRef path = CGPathCreateMutable();CGPathAddRect(path, NULL, self.bounds);
创建绘制区域
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef) string);
CTFramesetterRef 生成 CTFrame的工厂
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
生成CTFrame
CTFrame、CTLine、CTRun 关系如下图:(CTLine、CTRun后面会遇到)

CTFrameDraw(frame, context); 绘制
以上最简单的绘制结束
添加点击效果
添加之前我们先对绘制逻辑进行梳理
- 获取绘制区域、坐标翻转 –>
HHHyperLinkLabel : UIView - 生成绘制
frame–>HHFrameParser - 绘制 –>
HHHyperLinkLabel : UIView
根据逻辑将项目分类:

HHFrameParser新增
|
|
HHHyperLinkLabel变为
|
|
由此可见生成CTFrameRef时是需要一些参数的,而这些参数目前是从HHHyperLinkLabel中获取的

完全可以参数直接传给parser label仅仅用于展示,这样每一个类承担的功能就很单一

调用
|
|
其次观察到rect参数、大多数时候绘制高度是不确定的所以rect是不固定的、而最大宽度大部分时候是固定的,coretext可以根据给定的宽度来计算高度
|
|
计算完高度后一般会把高度回传出去来更新view高度,保证view刚好包含文字,此时Parser的输出物不仅仅是frame还有height,为了保证扩展性我们定义一个HHCoreTextData作为Parser输出的数据

HHFrameParser方法变更为
|
|
调用改为
|
|
此时效果

下面就是添加点击效果了
- 获取点击触摸点
- 判读触摸点是否在可点击文本范围内
- 如果在找到点击的是哪一个可点击文本
新增HHCoreTextDataUtil处理判断逻辑
|
|