一.UIView的绘制原理
UIView的绘制原理
如上图:
- 调用
[UIView setNeedsDisplay]
后, - 会调用系统的同名方法
[view.layer setNeedsDisplay]
方法 ,于是在当前view上面打上了一个脏标记; - 当前Runloop将要结束的时候才会调用
[CALyer display]
方法。然后进入到视图真正的绘制工作当中。 -
[CALayer display]
方法的内部实现当中,首先判断layer的delegate是否响应displayLayer这个方法。如果代理不响应(不实现)就会进入系统绘制流程;
面试考点:
问:我们调用[UIView setNeedsDisplay]方法的时候,不会立马发送对应视图的绘制工作,为什么?
调用[UIView setNeedsDisplay]后,会调用系统的同名方法[view.layer setNeedsDisplay]方法在当前view上面打上一个脏标记。当前Runloop将要结束的时候才会调用[CALyer display]方法,然后进入到视图真正的绘制工作当中。
面试考点:
问:是否知道异步绘制?如何进行异步绘制?
基于系统开的口子[layer.delegate dispayLayer:]
方法。
如果实现/遵从了dispayLayer这个方法,我们就可以进行绘制:里面需要做:
1)代理负责生产对应的bitmap
2)设置bitmap作为layer.contents属性的值
二.异步绘制流程
异步绘制流程
我们在某一个时机调用了setNeedsdispay方法
系统会在runloop将要结束的时候调用[CAlayer display]方法
如果我们的代理实现了dispayLayer这个方法,会调用dispayLayer这个方法。我们可以去子线程里面进行异步绘制,主线程可以做其他工作
子线程里面:
1)创建上下文、2)UI控件的绘制工作、3)生成对应的图片回到主线程,设置
[CALyer setContents]
,把绘制的视图显示在layer上面
三.系统绘制流程
系统绘制流程
- CALayer内部会创建一个backing store,我们可以理解为是CGContextRef 上下文;
- 系统会判断layer是否有代理,如果没有代理,会调用
[CALayer drawInContext:]
方法 - 如果有代理,会调用代理方法
[layer.delegate drawLayer : inContext]
,这个方法已经创建好上下文,可以在当前视图的绘制工作。这一步是发生在系统内部的。 - 然后在合适的时机给予我们一个回调方法,就是[UIView drawRect:]方法。
- 所有的工作最后通过CALayer上传上下文(backing store)到GPU。
[UIView drawRect:]默认是什么都不做,我们可以在这个基础上进行绘制工作。