iOS-CoreAnimation[1]-简介

本文对CoreAnimation的机制进行讲解。

Core Animation简介

Core Animation是iOS系统上用于处理图形渲染和动画的基础工具。对于动画的每一帧的绘画工作,Core Animation已经帮你完成了,只需要配置一下参数(开始点和结束点),Core Animation会自动处理物理图形硬件的渲染加速工作,从而达到更高的帧率和更平滑的动画效果而不会占用CPU以及减慢App的速度。

Core Animation处于UIKit/AppKit的下层,与Cocoa和Cocoa Touch的View工作流紧密相关,同时Core Animation也暴露了一些接口,可用于控制App的动画。

Architecture

Core Animation基础

Core Animation为动画的Views和其他可视的控件提供了一个通用的处理系统。Core Animation通过缓存Views中的内容到位图中,从而使其可以直接被图形硬件操作。在一些场景下,这种缓存策略可能需要你去重新思考App内容的管理和展示方式,但是通常,你不需要考虑这些。

你可以使用Core Animation去动画式地改变App的Views和可视的控件,例如位置,大小和透明度,尽可能不要把Core Animation当成动画片工具,不要一秒钟60次地替换一个View的内容。

Layers简介

Layers提供了绘图和动画的基础。
Layers是在一个3D空间中组织的3D平面,是Core Animation的核心。像Views一样,Layers管理平面的几何、内容和可视化属性等信息,但并没有定义自己的外观。一个Layer管理一个位图的状态信息,位图本身可以是一个View本身或者一张图片的绘画结果。因此,App中使用的主要Layers最好是模型化的对象,因为主要是它们在管理数据。

(1)基于Layers的绘图模型

大多数的Layers并不做任何可视化的绘图操作,而是,捕获App提供的内容,并缓存到位图中。当你改变了Layer的属性时,其实是在改变Layer对象的状态,当这些改变触发动画时,Core Animation将Layer的位图和状态信息传递给底层的硬件,在硬件操作位图比在软件中操作要快得多。

Layer-Drawing

由于操作一张静态的位图,基于Layers的绘图区别于传统的基于Views的绘图,基于Views的绘图一般调用drawRect:方法去重新绘图,这种方法将在主线程中占用CPU,代价昂贵。基于Layers的绘图可以用尽可能小的代价达到同样的效果。

(2)基于Layers的动画

Layer对象的数据和状态信息是与Layer在屏幕上呈现的内容解耦的,这给了Core Animation一种方式去处理从旧状态值到新状态值中间的变化。

Layer-Animation

Layer定义自身的几何信息

Layers其中一个工作就是管理其内容的可视化几何信息,包括边界,位置,旋转等。Layer跟View一样有frame和bounds矩阵,同时还有其他自身的属性,例如anchor point(锚点)。

(1)Layers使用两种坐标系

Layers使用两种坐标系,基于点的坐标系和单元坐标系。当Layer的属性值与屏幕的坐标或者其他Layer相关时,例如位置,使用基于点的坐标系。当与屏幕的坐标无关时,例如锚点,使用单元坐标系。

基于点的坐标系经常被用于表明Layer的大小和位置信息,对应bounds和postion属性,frame属性由这两个属性构成,但很少用。值得注意的是,其朝向与系统相关,iOS的起始点是左上角。

Layer-Geometries

单元坐标系用于呈现那些随着Layer Size变化而变化的属性,每个坐标值的范围在0到1之间,例如锚点。

Layer-Coordinate

为了保证精确地定位,所有坐标系的值都是float型。

(2)Anchor Points(锚点)对几何操作的影响

Layer与几何相关的操作都与锚点相关,最明显的是postion和transform两个属性。position属性是位于Layer的中心的,其定义随着锚点的值改变而改变,如下图:

Layer-AnchorPoint-Position

transform是绕着锚点旋转的,如下图:

Layer-AnchorPoint-Transform

(3)Layers可以进行三维运算

每个Layer有两个transform矩阵,可以用于操作layer以及其内容, 分别是:tranfrom属性可以对layer及subLayers起作用,sublayerTransfrom属性只对subLayers起作用。矩阵运算公式如下图:

Layer-Transform

常见的转换矩阵如下图:

Layer-Matrix

Layer树反映动画状态的不同方面

一个使用Cora Animation的App包含三种集合的Layers对象。

(1)Modal Layer Tree(Layer Tree)是最常用的与app交互的集合,其储存了任何动画属性的目标值

(2)Presentation Tree包含了正在运行的动画的当前值,例如进度等。

(3)Render Tree,渲染呈现动画,Core Animation私有,不可调用。

每一种Layer集合都是按照类似View的层级结构组织的,事实上,如果一个App对其所有View启用Layer,则起始的Layer的层级结构与View是完全对应的。但是,App可以添加其他的Layer对象到层级中,哪怕与View无关,如下图,subLayer1和subLayer2都是独立的Layer。

Layer-Hierarchy

Modal Layer Tree中的每一个Layer对象,同时有一个对应的Layer对象在Presentaion和Render Tree中。

Layer-LayerTree

注意:一般情况下都不需要访问Presentation Tree,如果必须要访问时,必须当动画在运行时才行。

Layers与Views的关系

Layers并不是Views的替代品,不能创建一个完全由Layers对象构成的可视界面,Layers让Views内容的绘图和动画更便利和高效。然而,Layers不能处理Events,绘制内容,参与响应链,以及其他Views做的事情。

在iOS系统上,每个View都是layer-backed,系统自动创建一个Layer对象,并于View同步。OSX系统上可以创建Layer-hosting的View,在这种情况下,在View变化时,AppKit不对Layer进行操作。

另外,可以创建与View无关的Layer对象,并将其嵌入到任何Layer对象下作为SubLayer。例如,可以将一张图片加载到一个单独的Layer对象中,然后在不同的场景中使用,这样可以避免将同一张图片在内容中创建多个副本。