《iOS Core Animation Advanced Techniques》学习笔记(二)

1. The Layer Tree

Ogres have layers. Onions have layers. You get it? We both have layers.
——Shrek

  • Core Animation 的名字很容易引起误解,让大家都认为它的主要目的是实现动画的,实际上动画只是 Core Animation 框架的功能之一,Core Animation 框架最开始的名字是 Layer kit。

  • Core Animation 是一个组装引擎(compositing engine),它的工作是尽快地将屏幕上的各块独立的内容组合起来用来展示。这些由各独立内容组合起来的层级结构就是 layer tree

  • Layers 和 Views 的关系:表面上看,UIView 和 CAlayer 一样,都是方形的,可以通过叠加组成层级关系,可以展示图片、文字、颜色等内容,可以管理子层级的位置,可以执行动画;实际上,对于 UIView,关于渲染(rendering)、布局(layout)、动画(animation)的这些工作,都不是由 view 自己处理的,而是 layer 处理的;唯一一个 CALyer 不能处理而由 UIView 自己处理的任务是触摸事件等用户交互。

  • 每一个 UIView 都有一个叫做 layer 的 CALayer 属性。也就是常说的 backing layer,view 的职责就是创建和管理这个 layer,来保证当添加或移除 subviews 时,layer 层也在添加或移除相应的 layer。

  • 实际上,UIView 在屏幕上的展示和动画都是由 backing layers 来实现的,UIView 只是一个 CALayer 的简单的封装,只提供一些像触摸事件响应等 iOS 独有的功能,以及一些 Core Animation 底层功能的高级接口。

  • 为什么 iOS 有这两个分别基于 UIView 和 CALayer 的并列层级?为什么不是一个能够管理所有任务的层级?原因就在于分清职责,避免代码重复。

  • 在 iOS 和 Mac OS 上,对事件(event)和用户交互(user interaction)的处理方式是不同的;处理手势操作和处理鼠标键盘的机制是不同的,所以 iOS 中有 UIKit 和 UIView,而 Mac OS 有 AppKit 和 NSView,它们的功能很相似,但是实现方式却有显著的差异。

  • 渲染(rendering)、布局(layout)、动画(animation)这些功能在iPhone、iPad等触屏设备上和在 MacBook 等非触屏设备上是一样的。通过将这些功能相关的逻辑单独分离出来成 Core Animation 框架,Apple 就能够在 iOS 和 Mac OS 之间共享这些代码了,这对于Apple 自家的 OS 开发团队以及那些要开发能在两个平台都能运行的 app 的第三方开发者来说,事情变得更简单了。

  • 事实上,除了 view hierarchylayer tree 这两个层级之外,还有 presentation treerender tree 另外两个层级,这四个层级,每个层级都扮演着不同的角色。

  • 如果 CALayer 不过是 UIView 内部的具体实现而已,那我们为什么还要去了解它?从某种程度上来讲,我们确实不需要接触 CALayer 就可以直接通过 UIView 得高级接口来绘制图形,实现动画。但是,使用简单同时也意味着失去了灵活性,如果你想实现一些与接口本身所提供的功能不一样,或者要使用一些 Apple 没有在 UIView 中暴露出来的接口时,你就需要倒腾一下偏底层的 Core Animation 了。

  • 那么,有什么事情是 CALayer 能做,而 UIView 做不了的呢?

  • 绘制带阴影、圆角、边框的图形(Drop shadows, rounded corners, and colored borders

  • 3D 变换(3D transforms and positioning

  • 不是方形的图形(Nonrectangular bounds

  • 视图内容上加一些遮罩(Alpha masking of content

  • 多步骤动画,非线性动画(Multistep, nonlinear animations

  • 大多数情况下,相比直接操作独立的 CALayer 对象,用带有 backing layer 的 UIView 对象来绘制图形,往往更简单,因为 UIVIew 有一些像 autoresizing、autolayout、event handling 等 CALayer 没有的功能。

  • 只有极个别情况下,你应该使用独立的 CALayer,而不是带有 backing layer 的 UIView:

    • You might be writing cross-platform code that will also need to work on a Mac.
    • You might be working with multiple CALayer subclasses and have no desire to create new UIView subclasses to hostthem all.
    • You might be doing such performance-critical work that even the negligible overheadof maintaining the extra UIView object makes a measurable difference (although inthat case, you’ll probably want to use something like OpenGL for your drawinganyway).

你可能感兴趣的:(《iOS Core Animation Advanced Techniques》学习笔记(二))