Core Animation是iOS动画实现的基础框架,它负责实现视图和其他可见元素的动画效果。Core Animation框架本身并不会进行图形的绘制工作,它的核心是通过CALayer对象来管理视图中展现的内容。CALayer会将可是内容缓存为bitmap然后将剩余的绘制工作交给图形硬件。
Core Animation实现动画的原理,大多数都是通过修改例如:大小、位置、透明度等图层属性来实现的。一个Core Animation的实现流程如下:
Core Animation中的树形结构
在Core Animation中有三个相互关联的图层树结构。每一个都反映了动画的不同的状态,在呈现App的内容的过程中扮演中不同的角色。
Layer Tree:在这个树中的对象负责存储所有动画的目标值的模型对象。无论何时需要改变图层的属性值,你使用的始终是其中的一个模型对象。
Presentation Tree:呈现树中的对象包含所有运行中的动画的瞬时值。图层树对象包含的是动画的目标值,而呈现树中的对象代表显示在屏幕上动画的当前值。
Render Tree:渲染树是动画的最终实现,并且属于Core Animation中的私有部分。
其中的每一个图层集合就像App中的View一样,按照树形结构组织在一起来管理。而且View层面的树形结构都会有一个对应的Layer层面的树形结构对应。当然我们也可以直接添加Layer对象而不必添加SubView,这表明Layer层面的树形结构不一定有一个相关的View层面树形结构与之对应。
对于Layer Tree的树形结构中的对象,Presentation Tree和Render Tree中都存在与之对应的对象。正如前面提到的,在动画实现的大部分时间里我们都是与Layer Tree中的对象进行交互的,但是我们想访问动画过程中的某些数值的时候就会需要使用Layer Tree对象的presentationLayer属性。
Presentation Tree中的对象表示了图层在屏幕中的瞬时值,因此只能在动画的进行时才能访问。而Layer Tree中的数值表示的动画最终的目标值。
CALayer与UIView
我们可以很清楚的发现CALayer实际上位于整个框架核心和基础的位置。那么它与我们编写代码中的常用的UIView是何种关系呢?其实两者在概念是类似的,都是通过层级关系树来管理矩形块以及其中可能包含的文本、图片、背景色等内容。最大的不同在于UIView会出现在用户事件的响应链当中并且处理这些交互,而CALayer则没有这些能力(虽然CALayer有时会被用来判断用户点击的位置是否在区域内)。
UIView与CALayer的层级其实是平行的,也就是说每个UIView的实例都会创建对应的CALayer属性实例。这样就能保证在View层面对SubView进行操作的时候能够在关联的Layer层面实现对应的效果。可以说View层就是基于Layer层进行了一层封装实现了更抽象的API接口以及交互处理的能力。之所以要这样做而不是采用一个简单的层级的原因就是:iOS的Cocoa Touch架构是从macOS的Cocoa架构演化而来,两者在Layer层的展现是类似的而在View层上的交互处理差别是巨大的。采用这种平行层级结构可以实现职责分离和解耦并且最大程度上避免不必要的重复代码方便维护。图层不是视图的替代品,我们无法创建一个基于单一图层对象的可视界面。不过图层能让视图的绘图和动画更简单和高效,并且能在绘图和动画时保持高帧率。可以说UIView的内部实现其实就是CALayer对象,所以我们可以深入到Layer层面对View层面的简单动画进行拓展来获得更高的灵活性。
原文链接:https://www.f2er.com/swift/322546.html