做iOS开发也有一段时间了,几乎每天都得和各种各样的View打交道,熟练使用View是做好iOS的基本功,正所谓知其然跟要知其所以然,所以今天就来学习视图到底是怎么工作的。
渲染机制
这张图是苹果官方 Core Animation
里面的截图、可以看出渲染视图的流程是
GPU -> OpenGL / Core Graphics -> CA -> UIKit/AppKit
详细的过程如图:
1、设置Layer的属性. frame, alpha, backgroundColor等
2、创建backing image: 无论是通过setContents将一个image传给layer,还是通过 drawRect
或 drawLayer:inContext
画出来的, drawRect:
等函数在这个阶段被调用
3、准备工作: CA准备渲染layer各种属性数据,准备传递给render server. 同时解压渲染的image. (除了 imageName:
方法从bundle加载的image会立刻解压之外,其他的比如直接从硬盘读入,或者网上下载的image不会立刻解压,在真正渲染的时候才解压)
4、提交:CA打包layer信息及动画参数,通过IPC(进程间通信)传递给render server。
5、数据到达render server后,会被反序列化成render tree。然后render server会根据layer属性,用OpenGL准备渲染
6、渲染到屏幕。
上面这些内容参考来自 这里 ,里面有更详细的解释。对性能优化有非常大的帮助。
交互方式
这是苹果官方文档里面的一个截图,解释了视图的工作原理,如何去响应事件。
- UIKit把事件打包成
UIEvent
对象,并分发到相对应的视图。 - 在事件回调的代码里可以处理视图的相关问题。
- 改变视图或者子类属性(frame, bounds, alpha)
- 调用
setNeedsLayout
方法更新视图布局 - 调用
setNeedsDisplay
或者setNeedsDisplayInRect:
方法重绘视图 - 通知控制器改变数据
- 如果视图有几何上的改变,UIKit会根据下面的规则来更新子视图:
- 如果使用了
Autoresizing
,则会根据这些规则来调整视图 - 如果实现了layoutSubView方法,则UIKit会调用它。
- 如果使用了
- 任何已经更新了的视图会和已可见的视图混合一起,提交给图形硬件去显示。
- 渲染到屏幕上。
UIView和CALayer关系
CALayer
是QuartzCore库内的类。是iOS基本的绘制单元。 UIView是CALayer的上层封装,增加了事件的处理。UIView里面好多属性都是和CALayer里面一一对应的。
UIView好比一个容器,用来管理视图,显示视图、处理事件;CALayer则着重视图的绘制
更详细的资料可以参考 这里
Offscreen Render(离屏渲染)
1、有些效果不能直接会知道屏幕上,必须先会知道一个offscreen的image contentext上,这种操作会引入而外的内存和CPU消耗。( rounded corners
, layer masks
, drop shadows
, layer rasterization
)
2、实现了 drawRect
或者 drawLayer:inContext
,为了支持任意的绘制, Core Graphic
会创建一个大小跟需要画得view一样的backing image。并且画完后传输到render渲染。
更详细的资料可以参考 这里
参考资料
http://foggry.com/blog/2015/05/06/chi-ping-xuan-ran-xue-xi-bi-ji/?utm_source=tuicool&utm_medium=referral
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=297
http://oncenote.com/2015/12/08/How-to-build-UI/