谈谈iOS中的View和动画

jopen 8年前

做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: 方法重绘视图
    • 通知控制器改变数据
    </li>
  • 如果视图有几何上的改变,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://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/

      </div>

      来自: http://www.liuchendi.com/2016/01/11/iOS/32_TalkAboutView/