Core Animation Programming Guide - Core Animation Basics

Core Animation Basics

Core Animation 为你的 app 提供视图和其余视觉元素的通常动画建立。Core Animation 并非替代你 app 的视图,它是一种集成在视图中为视图内容提供更好性能和支持的动画技术。它经过缓存视图内容到位图实现,能够直接地被图形硬件操做。有时这种缓存行为须要你屡次考虑怎么呈现和管理你 app 的内容,可是多数时候你使用 Core Animation 并不须要知道这种缓存技术。除了缓存视图内容,Core Animation也定义一种方式来明确任意的视图内容,并集成此内容到你的视图中和其余的一块儿表现动画。html

你用 Core Animation 把 app 视图和可视对象的变化用动画的形式表现出来,大多数都是经过修改视图的属性,好比,你可能使用 Core Animation 更新视图的position,size或者 opacity。Core Animation 根据你指定的属性值和现有值的不一样造成动画。你不须要想卡通动画那样每秒60次的替换视图内容,只须要在屏幕中移动视图、淡入淡出视图内容,应用任意的图形形态到视图,或者改变视图的可视属性。ios

Layers Provide the Basic for Drawing and Animations

Layer 对象 是在3D空间中组织成的2D界面,是Core Animation 的核心。像视图同样,layer 管理着几何、内容和界面的可视属性之类的信息。不一样于视图的地方是它并不定义本身的形态。一个 Layer 仅仅管理围绕着位图的状态信息。位图自己既能够是视图的最终绘制形态,也能够是一张你指定的图片。所以,你在 app 中使用的核心 layer 主要管理的是数据,能够当作数据模型。这一点须要谨记,它会影响到动画的效果。缓存

The Layer-Based Drawing Model

在你的 app 中,大部分的 layer 并不作实际的绘制,只捕捉 app 提供的内容并缓存它们到位图中,此位图有时被做为 backing store 。缓存到位图以后修改 layer 的属性,实际修改的都是 layer 对象相关的状态信息。当 layer 的属性值变动触发动画时,Core Animation 传递 layer 的位图和状态信息给图形卡,图形卡根据状态信息渲染位图,如图 1-1 。用硬件渲染位图比在软件中快不少。性能优化

图 1-1 How Core Animation draws content
app

因为是直接操做静态的位图,layer-based 的绘制技术彻底不一样于 view-based 的绘制技术。view-based 绘制,是视图改变后调用自身的方法 drawRect: 根据新的参数重绘,这种方式会下降性能,由于重绘的动做是经过 CPU 计算后在主线程上完成的。Core Animation 经过图形卡操做缓存的位图分担了CPU的负担来完成形似或相同的效果。框架

尽管 Core Animation 尽量的使用缓存内容,你的 app 仍是得提供内容的初始化和一次次的更新。Providing a Layer's Contents 这一章节中会详细地描述怎么为你的 app 提供 layer 内容对象。ide

Layer-Based 动画

layer 对象的数据和状态信息从屏幕的内容呈现中解耦出来。这种解耦为 Core Animation 提供了一种方式插入到自身,并以动画的形式展示状态值的变动。例如,修改 layer 的position 属性会致使 Core Animation 把 layer 从当前位置移动到新的位置。其余属性的修改也会产生相似的动画。图 1-2 展现了几种你能够在 layer 中表现的动画类型。在 Animatable Properties中列出了能够触发动画的 layer 属性。性能

Figure 1-2 Examples of animations you can perform on layers
测试

在一次动画期间,Core Animation 在硬件上为你绘制了全部的图形框架。你所须要作的只是明确动画的起始点。一样地你也能够能够根据须要自定义动画的参数和时间,若是你没有自定义这些参数和时间,Core Animation 会提供合适的缺省值。优化

怎么初始化、配置动画参数的信息,详见 Animating Layer Content

Layer Objects Define Their Own Geometry

layer的其中一项工做就是根据其内容管理视觉几何图形。可视几何图形包括各类信息,诸如内容的 bounds、在屏幕上的 position,以及layer是否已经发生旋转、缩放、变形。像视图同样,layer 也有能够用来定位和展示内容的 frame、bounds。layer 也有一些视图不具备的属性,像定义操做发生点的 anchor point。一些列举 layer 几何图形的方面是明显不一样于视图的。

Layers Use Two Types of Coordinate Systems

layer 利用 point-based coordinate systmes(基于点的坐标系统)和unit coordinate systems(单元坐标系统)明确内容的放置。坐标系统的使用依据被传递的信息类型。Point-based 坐标在有明确的屏幕坐标值或被明确地关联到另个一 layer 时使用,例如 layer 的 position 属性。Unit 坐标在属性值和屏幕坐标无关联但和其余有关联时使用,例如,layer 的 anchorPoint 坐标,它指出了一个和 layer 自身的bounds关联且能够修改的点。

point-based 坐标大多数时候经过 layer 的 bounds 和 position 属性明确 layer 的 size 和 position。bounds 定义了 layer 的坐标系统,包含 layer 在屏幕上的尺寸。position 属性定义了layer相对于父层坐标系统的定位。尽管 layer 有 frame 属性,其实 frame 源于 bounds 和 position 两个属性,使用的频次不高。

layer 的 bounds 和 frame 方向和平台的默认方向相匹配。图 1-3 展现了bounds 和 frame 在 ios 和 os x上的默认方向。ios中,bounds的原点方向默认在 layer 左上角,而 os x 中默认在左下角。若是你在 ios 和 os x 之间共享 Core Animation 的相关代码,须要注意两个平台的这点差别。

Figure 1- 3 The default layer geometries for iOS and OS X

在图 1-3 中须要注意一点,position 属性被定位在 layer 的正中间,这个属性值的明显变化是众多基于 layer 的 anchorPoint 属性值之一。锚点表明肯定的坐标原点的点,在 Achor Points Affect Geometric Manipulations 中有详细的概述。

锚点是众多使用 unit 坐标系统来肯定属性值的属性之一。在 layer 的 size 属性改变时会影响一些属性的改变,unit 坐标系统在Core Animation 中就是用来表明这些属性的。你能够认为 unit 坐标就是可能值的具体百分比。在 unit 坐标控件中每个坐标的范围是 0.0~1.0 。例如,在 x 轴方向上,左边距的坐标是 0.0,右边距则是 1.0 。在 y 轴方向上,unit 坐标值的变化取决于平台,若是 1-4 所示。
Figure 1-4 The default unit coordinate system for iOS and OS X


注意:在 OS X 10.8以前,geometryFlipped 属性能够在须要的时候修改 y 轴的默认方向。当 layer 包含翻转变化时layer就须要这个属性来修改方向。例如,若是父视图使用了翻转变形,它的子视图(他们相关的layer)将经常被倒置,在这时 设置子视图们的 geometryFlipped 属性为 YES 将是组简单的解决方式。OS X 10.8 和以后的系统中,AppKit 为你管理这个属性。对于 iOS 应用,最好不要使用这个属性。


全部的坐标值,不管是坐标点仍是 unit 坐标都是浮点数。浮点数的使用能够指出可能介于正常的坐标值之间位置的精确值,并且还很方便,尤为是打印时或者绘制一个点表明多个像素的 Retina 显示时。浮点数的使用可让你忽略对设备展现的依赖,仅仅须要指出你想要的精度值便可。

Anchor Points Affect Geometric Manipulations

你能够用 layer 的 achorPoint 属性来操控 layer 的集合形状。最值得注意的是锚点的改变会影响到 position 或 transform 属性的操做。position 属性老是依赖于layer 的锚点来明确,而任何你应用的变形也取决于相关的锚点。

图 1-5 说明了锚点从默认值改变为另外一值时对 layer 的position 属性的影响,尽管 layer 没有在父层的 bounds 中并无移动,从 layer 的中心移动锚点纸 layer 的 bounds 原点改变了 position 属性值。

图 1-5 How the anchor point affects the layer's position property

图 1-6 展现了原点的变化怎样影响应用在 layer 上的变形。当你在 layer 上应用旋转变形时,旋转是以锚点为中心。由于锚点默认被设置在 layer 的中间,此时能够产生你所指望的旋转形态,然而更改了毛点后,旋转的结果就不一样了。

图 1-6 How the anchor point affects layer transformations

Layers Can Be Manipulated in Three Dimensions

每个 layer 都有两个 transform 矩阵,你能够用来操控 layer 和它的内容。CALayer 的 transform 属性指出了你想应用在 layer 和它内嵌的子 layer形态。通常在你想修改 layer 自身时用这个属性。例如,你能够用此属性等比例缩放或旋转 layer 或 改变 暂时性地改变 position。sublayerTransform 属性定义了额外的变形,仅仅用在子 layer 中,经常用来往图形内容中单独添加可见视觉现象。

Transform 依靠数值矩阵的多个坐标值得到新的坐标集,此作标记表明原点变形后的版本。Core Animation 的值能够在三维中指出,因此每一个坐标点有四个值,能够用 4x4的矩阵标示,如图 1-7 。图形中的 transform 对应 CATransform3D 类型。幸运的是你不用直接修改这个结构的字段来造成一个变形,Core Animation提供综合的方法集来建立 scale, translation和 rotation 矩阵,并且能够作矩阵比较。另外关于方法操做变形,Core Animation 用键值对的编码,支持直接用键值改变变形。你能够修改的键列表,详见 CATransform3D Key Paths

图 1-7 Converting a coordinate using matrix math

图 1-8 显示了通常变形中你会用到的矩阵配置。身份坐标值和其余坐标值的乘积返回的仍是一样的坐标。其余的变形中坐标怎么被修改彻底依赖矩阵元素的改变。例如,沿着X轴移动,你只须要为矩阵中的 tx 元素提供一个非零的数值,把 ty 和 tz 的值设为 0 便可。再好比旋转,你提供旋转角度的正弦、余弦值就好了。

图 1-8 Matrix configurations for common transformations

你能够建立和操做变形的相关方法,详见 Core Animation Function Reference

Layer Trees Reflect Different Aspects of the Animation State

一个 app 在使用 Core Animation 时有三个 layer 对象集。当 app 的内容在屏幕显示时每一 layer 对象集都扮演着不一样的角色:

  • layer 模型树对象(或简称 layer 树)是你的 app 中交互最多的。其中的对象属于模型对象,用来储存动画相关的目标值。在你改变一个 layer 的属性时使用的就是这些对象。
  • presentation 树对象包含的是动画在执行中的状态值。其中的目标值表明的时当前动画在屏幕上呈现的当前值。你能够用这些对象读取当前动画值可是别修改。
  • render 树对象是 Core Animation 私有的,专门变现实际的动画。

每个 layer 对象集在 app 中都是像视图同样以层次结构组织起来的。事实上在 app 的全部视图中,有效的 layer 在初始时是何视图的层次机构相匹配的。app 能够根据需求添加额外的 layer 对象到已有的 layer 层次中(layer 和 view 是不相关的),当对一个视图的最顶层不须要的内容就行性能优化时你可能会用到。图 1-9 展现了 layer 在一个简单 ios app 中的分解。示例中的 window 包含内容视图,内容视图包含一个 button 视图和两个单独的 layer 对象,每个视图都有相关的 layer 对象,它们一块儿构成了 layer 的层次。

图 1-9 Layers associated with a window

如图 1-10,对于每个 layer 树的对象,presentation 和 render 树对象是一一对应的。正如以前提到的,app 主要用 layer 树中的对象工做,有时会访问 presentation 树的对象。使用 layer 树的对象 presentationLayer 能够得到 presentation 树相关的对象。当动画进行时你可能会想得到属性的相关值,访问这个对象便可。

图 1-10 The layer trees for a window


重要提示:你只能在动画进行时访问 presentation 树的对象。在动画的进行过程当中,presentation 树包含 layer 显示在屏幕上那一瞬间的各类值。这种行为和 layer 树相比是彻底不一样的,layer 树老是反应你代码的最终值,也就是动画最终的状态。


The Relationship Between Layers and Views

layer 并非你 app 中视图的替代,你不能在一个单独的 layer 对象上构建一个可视界面。Layer 能够为你的视图提供基础设施。最明确的一点就是 layer 能够提升视图内容的绘制和动画的效率和框架率。可是还有一些其它的 layer 完不成,不能处理事件,绘制内容,成为响应链的一环,或者其它的一些事情。所以每个 app 必需要有一个或多个视图来处理这类的交互。

在 iOS 中,每个视图都是构建在一个相关的 layer 对象之上,在 OS X 中须要你手动决定哪一个视图应该有 layer。在 OS X v10.8 及以后的版本中,为全部视图添加 layer 是比较合情理的,可是这也不是必须的,你仍然能够为那些不合理的视图内容禁用 layer。Layer 的使用确实会增长 app 的内存使用,可是它的使用利大于弊,因此在禁用 layer 时最好测试一下 app 的性能。

当你开启 layer 对一个视图的支持时,此视图就被做为一个 layer-backed 视图。在 layer-backed 视图中,系统负责建立视图之下的 layer,保持视图和 layer 之间的同步。全部的 iOS 视图都是 layer-backed 视图,OS X 大部分视图是。可是在 OS X 中你能够建立一个 layer-hosting 视图,一个你为其提供 layer 对象的视图。关于 layer-hosting 视图,AppKit 提供了 layer 方便的管理方式,不用在视图的响应变换时修改它。


注意:对于 layer-backed 视图,强烈建议你尽量的管理视图而不是它的 layer。在 iOS 中,视图仅仅是对 layer object的封装,所以你对 layer 的操做通常都会正常运行。可是不管是 ios 仍是 os x,都出现过用修改 layer 代替视图修改时发生错误的情况。本文档会尽量的指出这些误区。


尽管 layer 和视图有关联,你仍然能够建立一个和视图不相关的 layer 对象。你能够把这个单独的 layer 对象嵌入到其余的 layer 对象中,而后把他们和一个视图相关联。在性能优化时通常会采用此方法。例如,若是你想在多个地方使用同一张图片,你能够只加载一次这张图片,把它和几个单独的 layer 对象相关联,而后把他们加入到 layer 树中,那么每一个 layer 都会引用它,而不是从新 copy 到内存中。

怎么在 app 中为视图启用 layer,详见 Enabling Core Animation Support in Your App。关于怎么建立 layer 对象层和其余的提示,详见 Building a Layer Hierarchy

相关文章
相关标签/搜索