谈谈iOS中的View和动画
做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会调用它。 </ul> </li>
- 任何已经更新了的视图会和已可见的视图混合一起,提交给图形硬件去显示。
- 渲染到屏幕上。 </ul>
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://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=297
http://oncenote.com/2015/12/08/How-to-build-UI/
</div>来自: http://www.liuchendi.com/2016/01/11/iOS/32_TalkAboutView/