博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Core Animation Programming Guide - Core Animation Basics
阅读量:5333 次
发布时间:2019-06-15

本文共 7160 字,大约阅读时间需要 23 分钟。

Core Animation Basics

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

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

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

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

尽管 Core Animation 尽可能的使用缓存内容,你的 app 还是得提供内容的初始化和一次次的更新。 这一章节中会详细地描述怎么为你的 app 提供 layer 内容对象。

Layer-Based 动画

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

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

basics_animation_types_2x.png

在一次动画期间,Core Animation 在硬件上为你绘制了所有的图形框架。你所需要做的只是明确动画的起始点。同样地你也可以可以根据需要自定义动画的参数和时间,如果你没有自定义这些参数和时间,Core Animation 会提供合适的缺省值。

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

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

layer_coords_bounds_2x.png

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

锚点是众多使用 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 用键值对的编码,支持直接用键值改变变形。你可以修改的键列表,详见 。

图 1-7 Converting a coordinate using matrix math

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

图 1-8 Matrix configurations for common transformations

你可以创建和操作变形的相关方法,详见

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,详见 。关于怎么创建 layer 对象层和其他的提示,详见 。

转载于:https://www.cnblogs.com/1oo1/p/4230465.html

你可能感兴趣的文章
【luogu P2298 Mzc和男家丁的游戏】 题解
查看>>
前端笔记-bom
查看>>
MATLAB作图方法与技巧(一)
查看>>
上海淮海中路上苹果旗舰店门口欲砸一台IMAC电脑维权
查看>>
Google透露Android Market恶意程序扫描服务
查看>>
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
eclipse-将同一个文件分屏显示
查看>>
mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!
查看>>
对闭包的理解
查看>>
练习10-1 使用递归函数计算1到n之和(10 分
查看>>
Oracle MySQL yaSSL 不明细节缓冲区溢出漏洞2
查看>>
windows编程ASCII问题
查看>>
.net webService代理类
查看>>
Code Snippet
查看>>
Node.js Express项目搭建
查看>>
zoj 1232 Adventure of Super Mario
查看>>
1201 网页基础--JavaScript(DOM)
查看>>