YYText 源码解析 —— YYLabel (一)

架构

YYText 源码解析 —— YYLabel (一)_第1张图片

(引用作者框架对比图片)

YYText包括控件(YYLabel,YYTextView),布局(YYTextLayout,NSAttributedString,YYTextContainer),核心(CoreText)。

源码目录组织

YYText 源码解析 —— YYLabel (一)_第2张图片

YYLabel

继承关系

YYText 源码解析 —— YYLabel (一)_第3张图片

YYLabel 直接继承 UIView,作者自己实现 Label 的渲染。+_+

state

struct {
            
// 是否需要更新布局
unsigned int layoutNeedUpdate : 1;
unsigned int showingHighlight : 1;

unsigned int trackingTouch : 1;
unsigned int swallowTouch : 1;
unsigned int touchMoved : 1;

unsigned int hasTapAction : 1;
unsigned int hasLongPressAction : 1;

// 内容是否支持逐渐消失
unsigned int contentsNeedFade : 1;
    } _state;

如何熏染出 Text

YYLabel 的熏染是通过 YYTextAsyncLayerDelegate 完成。 YYTextAsyncLayerDelegate 提供了 newAsyncDisplayTask 配置方法用来实现渲染。

YYTextAsyncLayer 与 YYLabel 的熏染流程

setText 为例,看看这个熏染的流程。

YYText 源码解析 —— YYLabel (一)_第4张图片
  • [self.layer setNeedsDisplay] 这里调用的是 YYTextAsyncLayersetNeedsDisplay 。因为 layerClass 方法被重写了,返回了 YYTextAsyncLayer 。所以主layer所使用的类是 YYTextAsyncLayer
  • _cancelAsyncDisplay 的实现,后续再探讨。。。记遗留问题。
  • 这里 display 也被重写了,在这了执行了渲染最为关键的函数 _displayAsync
  • YYTextAsyncLayer 提供了 displaysAsynchronously 用来控制是否进行异步渲染,默认为异步熏染。

熏染

本人对 Core Graphics Framework 部分不同熟悉,个人重点对这一块代码进行学。刚才我们发现这里的渲染分为:普通渲染(ps:不知道怎么称,叫同步渲染感觉不太适合,就叫普通渲染吧)和异步渲染。这两种渲染的渲染代码处理基本是一样的,只是异步熏染增加了一些多线程的处理的考虑(比如:多线程经典的“读与写”的问题)。

所以就直接学习普通渲染部分的代码吧#^_^#

YYTextAsyncLayer 熏染学习

UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, self.contentsScale);
CGContextRef context = UIGraphicsGetCurrentContext();

if (self.opaque) {
    CGSize size = self.bounds.size;
    size.width *= self.contentsScale;
    size.height *= self.contentsScale;
    CGContextSaveGState(context); {
        if (!self.backgroundColor || CGColorGetAlpha(self.backgroundColor) < 1) {
            CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
            CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height));
            CGContextFillPath(context);
        }
        if (self.backgroundColor) {
            CGContextSetFillColorWithColor(context, self.backgroundColor);
            CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height));
            CGContextFillPath(context);
        }
    } CGContextRestoreGState(context);
}

task.display(context, self.bounds.size, ^{return NO;});
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.contents = (__bridge id)(image.CGImage);
  • 开始是调用 UIGraphicsBeginImageContextWithOptions 创建一个图片处理的上下文。 绘制结束调用 UIGraphicsEndImageContext
  • 通过 UIGraphicsGetCurrentContext 获取当前图形的上下文。
  • 这里有个 opaque 属性表示是否不透明,详细属性参见。
  • CGContextSaveGState 把上下文保存到栈中。然后通过 CGContextSetFillColorWithColor 设置填充颜色, CGContextAddRect 添加矩形,CGContextFillPath 填充上下文路径。 最后保存通过 CGContextRestoreGState 保存最近的上下文。
  • 调用 task.display 回调,这里是调用配置的渲染方法,后面再分析 YYLabel 的熏染回调。 YYLabel 的熏染主要通过 YYTextLayout 来处理。 这么后续再做学习。
  • 通过 UIGraphicsGetImageFromCurrentImageContext 当前的上下文绘制出来的图片,结束绘制。
  • 最后将图片赋值给 contents 属性完成熏染。

你可能感兴趣的:(YYText 源码解析 —— YYLabel (一))