UIView的绘制流程梳理

最近开始用思维导图工具,梳理一些知识点,但是长篇大论还是只能交给markdown。

 

1.UIView的绘制流程

UIView的绘制流程梳理
UIView的绘制流程

上图的流程基本和https://blog.csdn.net/jingqiu880905/article/details/51851534/这里所说的一致。

我们发现drawRect:调用时机是比较靠后的,而且它会决定绘制流程的走向。重写了drawRect:也就意味着,layer会被调用setNeedDisplay方法。而drawRect:作为View层面暴露给使用者的绘制入口,是因为UIView实现了drawLayer:inContext:方法,它内部会调用drawRect:。

UIView作为layer的delegate,除了drawRect:外,还有两个绘制入口displayLayer:和drawLayer:inContext:。相比于drawRect:会自动被调用,后两者需要手动调用layer的setNeedDisplay方法才会被调用。

而layer层面,绘制入口只有drawInContext:,它的默认实现是调用delegate的drawLayer:inContext:方法。

 

 

 

关键测试代码如下:

@implementation MyLayer

- (void)drawInContext:(CGContextRef)ctx
{
    NSLog(@"%s",__FUNCTION__);
    [super drawInContext:ctx];
}

- (void)display
{
    NSLog(@"%s",__FUNCTION__);
    [super display];
}

- (void)setNeedsDisplay
{
    NSLog(@"%s",__FUNCTION__);
    [super setNeedsDisplay];
}
@end


@implementation MyView


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
//- (void)drawRect:(CGRect)rect {
//    NSLog(@"%s",__FUNCTION__);
//    [super drawRect:rect];
//}

+ (Class)layerClass
{
    return MyLayer.class;
}

//- (void)displayLayer:(CALayer *)layer
//{
//    NSLog(@"%s",__FUNCTION__);
//}

- (void)setNeedsDisplay
{
    NSLog(@"%s",__FUNCTION__);
    [super setNeedsDisplay];
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    NSLog(@"%s",__FUNCTION__);
    [super drawLayer:layer inContext:ctx];// 如果去掉此句就不会执行drawRect!!!!!!!
    CGContextAddEllipseInRect(ctx, CGRectMake(10,10,20,20));
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
    CGContextFillPath(ctx);
}
@end

 

上一篇:NSLog的各种打印格式符和打印CGRect相关结构体


下一篇:iOS进阶_KVC(&KVC赋值取值过程分析&KVC自定义&异常处理)