CoreAnimation简单的介绍.doc_第1页
CoreAnimation简单的介绍.doc_第2页
CoreAnimation简单的介绍.doc_第3页
CoreAnimation简单的介绍.doc_第4页
CoreAnimation简单的介绍.doc_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Core Animation是iOS与OS X平台上负责图形渲染与动画的基础设施。Core Animation可以动画视图和其他的可视元素。Core Animation为你完成了实现动画所需的大部分绘帧工作。你只需在配置少量的动画参数(如开始点位置和结束点位置)就可启动Core Animation。Core Animation将大部分实际的绘图任务交给了图形硬件处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速让动画具有更高的帧率且更加平滑,但这并不会增加CPU的负担而导致影响你应用的运行速度。如果你正在开发一个iOS应用,你就已经使用到了Core Animation;如果你开发的是OS X应用,你仅需小小的付出就可以利用Core Animation的强大功能。如下图,Core Animation位于AppKit和UIKit的底层。它被紧密的集成到了Cocoa和Cocoa Touch视图工作流中。虽然被紧密的集成,Core Animation也存在扩展功能的接口,这些接口暴露给了应用的视图。使用这些接口能让你更细粒度地控制应用中的动画。简介你可能从不需要直接使用Core Animation,但是当你使用Core Animation,你应该了解Core Animation是你app基础设施中的一部分。Core Animation管理着你的应用内容Core Animation自身并不是一个绘图系统。它只是一个负责在硬件上合成和操纵应用内容的基础构件。Core Animation的核心是图层对象,图层对象用于管理和操控你的应用内容。图层将捕获的内容放到一副位图中,图形硬件能够非常容易的操控你的位图。在大部分应用中,图层被作为一种管理视图内容的方式,但是你也可以创建标准的图层,这取决于你自身的需要。更改图层属性会产生动画你使用Core Animation创建的大部分动画都包含对图层属性的更改。像视图一样,图层对象也具有边框矩形、坐标原点、尺寸、不透明度、变换矩阵以及许多其他面向可视的属性(如backgroundColor)。大部分这些属性的值发生了变化都将会触发隐式动画被创建。隐式动画是一种从旧属性值动画到新属性值的动画形式。如果需要全面掌控动画行为,你可以考虑使用显式动画这些属性。有组织的图层层级有组织的图层之间存在着父子关系。图层的组织会影响到图层的可见内容。可见内容的管理与视图的管理方法相似。附到视图上的图层集合的层级镜像对应的视图层级。你可以将独立图层添加到图层的层级以扩充你的视图的可视内容。 使用动作对象改变图层的默认行为通过动作对象可以做到隐式的图层动画。动作对象是实现了一个预定义接口的常规对象。Core Animation使用动作对象实现与图层关联的常规的默认动画集合。你可以创建属于你自己的动作对象,以实现自定义的动画或者实现其他行为类型,然后你将动作对象赋值给图层的某一属性。当属性发生变化,Core Animation检索你的动作对象并告诉动作对象执行对应的动作。 如何使用该文档该文档为那些需要更全面的控制动画效果或打算利用图层提升绘图性能的开发者。该文档也介绍了iOS和OS X对图层和视图的合成。图层和视图的合成在iOS和OS X平台上是不同的,理解这些不同对于创建高效的动画至关重要。 预备知识你应该了解你的目标平台的视图架构,以及熟悉如何创建基于视图的动画。如果你还未到该阶段,请阅读以下两篇文档:对于iOS应用开发,你应该理解iOS视图编程指南中关于视图架构的描述。对于OS X应用开发,你应该理解视图编程指南中关于视图架构的描述。Core Animation基础Core Animation为动画视图和其他可视元素提供了一个通用的系统。Core Animation并不是视图的替代品,相反,它是一种和视图相集成的技术。由于位图可以直接由图形硬件直接操控,通过将视图的内容缓存到位图中, 该技术可获得更优的性能且支持动画视图内容。除了缓存视图内容,Core Animation也定义了指定任意可视内容,然后将内容和视图集成,最后动画视图和其他可视元素的方式。使用Core Animation让视图和可视对象的变化能以动画的形式呈现。大部分变化都与可视对象属性的更改相关。比如Core Animation能让视图的位置、尺寸或者透明度的变化以动画的形式呈现。当你更改了这些属性的值, Core Animation在当前属性值和最新指定的属性值之间进行动画。你一般不需要像卡通片那样,完成每秒60次的视图内容替换。相反,你应该利用Core Animation提供的移动视图、淡入淡出视图、对视图应用任意的变换、改变视图的其他可视属性的方式完成动画 。图层是绘图与动画的基础图层对象是组织在三维空间的二维平面。它是使用Core Animation执行任何操作的核心构件。和视图一样,图层的可管理信息包括几何结构、内容、可视属性;不同于视图,图层没有定义它自己的外观,图层仅管理周围位图的状态信息。位图可以是视图的绘图结果或者一张图片。因此主要的图层被认为是模型对象,因为它们主要是用于管理数据。此概念务必记住,因为它影响到动画的行为。 基于图层的绘图模型大部分图层不做实际的绘图操作。相反,图层捕获应用的内容并缓存它们到位图中。位图有时也被称为储备(backing store)。当你随后改变了一个图层的属性值,你做的所有只是改变了与图层对象相关联的状态信息。当你的更改触发了一个动画,Core Animation传递图层的位图和图层的状态给图形处理硬件。图形处理器所做的工作是使用获得的信息渲染位图,如图1-1所示,用图形处理硬件操纵位图要比图形处理软件能获得更高的动画效果。因为操纵的是静态的位图,基于图层的绘图和基于视图的绘图在技术上有明显的不同。对基于视图的绘图,对视图的改变经常会触发调用视图的drawRect:方法以重绘视图内容。但是此种方式的代价相对较高,因为它是CPU在主线程上的操作。Core Animation通过尽可能的使用图形硬件操纵缓存后的位图来避免了这种开销,从而完成相同或相似的效果。虽然Core Animation尽可能的使用缓存后的内容,但也必须提供初始内容并不时地更新它。 基于图层的动画图层的数据和状态信息是从图层内容的可视呈现中被分离了出来的。这种分离性给了Core Animation介入以及从旧的属性值动画到新的属性值的机会。例如改变一个图层的position属性会引起Core Animation将图层从当前的位置移动到新的具体位置。对其他属性做相似的改变将引起适当的动画效果。图1-2展示了一些可以执行在图层上的动画类型。图1-2 可在图层上执行的动画类型在动画运行期间,Core Animation使用硬件帮你完成每一帧的绘制工作。你只需要指定动画的开始点和结束点,剩下的交由Core Animation完成。如若需要,你也可以指定自定义时间信息和动画参数,如果你没有指定, Core Animation会提供适当的默认值。 图层对象定义了自己的几何结构图层的其中一项任务就是管理自身内容的可视几何。可视几何包含关于图层内容边界、在屏幕上的位置,是否图层已被旋转、缩放,或应用了某种变换。与视图类似,一个图层有一个frame和bound属性,你可以使用这两个属性来定位图层和它的内容。图层也有一些视图所没有的属性,比如anchor属性,任何变换操作都是围绕该点运转的(可以理解为一个按在图层上的图钉)。图层的某些几何概念的指定方式与视图信息的指定方式也有不同。 图层使用两种类型的坐标系统图层利用基于点的坐标系统和单位坐标系统指定内容的布局。坐标系统的选择依赖于被传达的信息类型。当指定的值是直接映射到屏幕或相对于其他图层的坐标,比如图层的position属性,则使用基于点的坐标系统。当指定的值是相对于一些其他的值,与屏幕坐标不相关联,则使用单位坐标。比如图层的anchorPoint属性,anchorPoint属性指定了相对于图层边界的一个点。anchorPoint属性可以更改。基于点的坐标最常用于指定图层的尺寸和位置。可通过图层的bounds和postion属性设定图层的尺寸和位置。bound定义了图层自身的坐标系统并包含图层在屏幕上的尺寸。position属性定义了图层相对于父坐标系统的位置。虽然图层有一个frame属性,该属性实际上是从bounds和position属性派生而来,极少被使用。图层的bounds和frame矩形的方向始终与底层平台的默认方向相匹配。图1-3显示了iOS和OS X平台上边界矩形的默认方向。在iOS中,默认情况下边界矩形的原点在图层的左上角。而OS X上边界矩形的原点则在左下角。如果你在iOS和OS X版本的app之间共享Core Animation代码,一定要对此种情况做区别对待。图1-3 iOS与OS X平台默认的图层几何结构注意到图1-3中position属性被定位在图层的中间位置。position属性的变化参照图层的anchorPoint属性。锚点是使用单位坐标系统的属性之一。Core Animation中使用单位坐标表示的属性值可能会因为图层的尺寸变化而发生改变。你可以把单位坐标当做是总数的百分比。在单位坐标系统空间中每一个坐标的取值范围在0.0和1.0之间。比如说,沿着x轴,左侧是0.0,右侧是1.0.沿着y轴,单位坐标值方向的不同依赖于具体的平台。如图1-4所示。图1-4 iOS和OS X平台默认的单位坐标系统注意:直到OS X 10.8才出现了geometryFlipped属性,该属性可以改变默认图层y坐标的方向。当翻转变换被调用时,使用该属性来调整图层的方向有的时候是必需的。如果父视图使用了翻转变换,它的子视图内容(以及它对应的图层)将经常被颠倒。在这种情况下,设置子图层的geometryFlipped属性为YES是一种修正该问题最简单的方法。在OS X 10.8及以上版本,AppKit负责管理该属性,你不应该更改它。对于iOS app,不推荐使用geometryFlipped属性。所有的坐标值,无论是点还是单位坐标都以浮点数指定。使用浮点数允许你更精确的指定可能落在整数坐标值之间的点。特别是打印或向retina屏幕绘图,浮点值都会很方便。浮点值允许你忽略底层设备的分辨率,而你只需要指定值的精度。 锚点影响几何结构的操作图层的几何操是相对于图层的锚点进行的,anchorPoint属性可以访问图层的锚点值。当改变图层的postion和transform属性值,锚点的影响就很明显。position属性是相对于图层的锚点被指定。并且任何你对图层阴影的变换操作也是相对于锚点。图1-5说明了改变锚点对图层position属性的影响。尽管图层没有在它的父边界内移动,将锚点从中心点移动到图层边界的原点将改变position属性值。图1-5 锚点是如何影响图层的position属性 图1-6显示了锚点的变化是如何影响到应用在图层上的变换。当你对图层应用了一个旋转变换,图层将围绕中心点旋转。因为默认情况下,锚点被设定在图层的中心位置。一般创建这类旋转行为正是你所期望的。然而如果你改变了锚点值,旋转的结果也会发生变化。图1-6 锚点是如何影响图层的变换 图层可在三维空间中操作 图层有两个操控图层和内容的变换矩阵,transform和sublayerTransform属性。CALayer的transform属性用来指定应用到图层和它内嵌的子层上的变换。通常当你想更改图层本身则使用该属性。比方说,你可能使用该属性缩放或旋转图层,或是临时的改变图层的位置。sublayerTransform属性定义了仅应用在子层上的变换以及给场景内容添加透视效果。变换行为由多个坐标确定,这些坐标通过一个数字矩阵来获取,获取的坐标结果是原始点被变换后的版本。因为Core Animation的值可在三维空间中指定,每个坐标点有四个值,这四个值需要和一个4*4的矩阵相乘。如图1-7所示。在Core Animation中,图中的变换由CATransform3D类型表示。幸运的是,你不需要直接更改这个结构中的域值来执行标准变换。Core Animation为创建缩放、平移、旋转矩阵以及矩阵比较提供了综合的函数集。除了使用函数操纵变换。Core Animation扩展了键值编码以支持你使用键路径更改一个变换操作。图1-7 使用矩阵数学转换一个坐标图1-8显示了对一些常见的变换矩的配置。任何坐标与单位矩阵相乘将返回完全相同的坐标。坐标如何被更改完全依赖于你变化的矩阵因子。比如,为了仅在X轴上平移,你只需对变换矩阵的tx因子应用一个非零值,并让ty和tz值为0。如果是旋转,应用一个旋转角度的正弦和余弦值。图1-8 常见变换的矩阵配置不同的图层树反映了不同的动画状态使用Core Animation的app拥有三个图层对象集合。每一个图层对象集合在呈现app内容上都扮演着不同的角色。模型图层树中的对象(或简称“图层树”)用的最多。在这个树中的对象是模型对象,模型对象负责存储所有动画的目标值。无论何时改变图层的属性值,你使用的始终是某一个模型对象。呈现树中的对象包含所有运行中的动画的瞬时值。图层树对象包含的是动画的目标值,而呈现树中的对象代表显示在屏幕上动画的当前值。你不应该更改这个树中的对象。相反,你使用这些对象来读取当前动画的值,可能用于创建开始于这些值的新的动画。在渲染树中的对象执行实际的动画,并且对Core Animation是不公开的。每一个图层对象集合被组织在一个层次结构中,类似于app中的视图。事实上,在一个所有视图都支持图层功能的app来说,每一个树的初始结构完全与图层的层次相匹配。一个app可以添加另外的图层对象,因此图层与视图是不相关联的。可以按照需求将图层对象插入到指定的视图层级中。你可能为了优化app内容的性能而选择加入图层对象而非视图,原因在于图层的开销要比视图低。图1-9展示了出现在一个简单iOS app的图层分解图。在示例中窗口包含了一个内容视图,内容视图包含了一个按钮视图和两个独立的图层对象。每一个视图拥有一个相对应的构成图层层次的图层对象。图1-9 与窗口相关联的图层在图层树中的每一个对象,在渲染树和呈现树中也存在一个与之匹配的对象。如图1-10所示。正如之前提到过的,app主要与图层树中的对象进行交互,但可能有时会访问呈现树中的对象。具体地,访问图层树中对象的presentationLayer属性将返回一个在呈现树中相对应的对象。你可能会通过该对象获取在动画执行过程中的某一时刻的属性值。图1-10 窗口中的图层树重要:只在动画运行时访问呈现树中的对象。当动画在进行中,呈现树就包含了图层显示在屏幕上的那一刻的值。该行为与图层树不同,图层树永远只表示最终的目标值。图层不是视图的替代品。因此无法创建一个基于单一图层对象的可视界面。图层是视图的基础设施。具体地,图层让视图的绘图和动画更简单和高效,并且能在绘图和动画时保持高帧率。然而许多事情图层无法做到。图层不能处理事件、绘制内容,特别是在响应链中,或是做一些其他的事情。因此,每个app必须有一个或多个视图来处理这类交互。在iOS中,每一个视图有一个相对应的图层对象。但在OS X中,你必须决定哪一个视图拥有图层。OS X 10.8以及之前的版本中,添加图层到所有视图上也许是有意义的。然而你不必这样做,你仍可以关闭图层防止不必要以及无根据的开销。图层在某种程度上减少了程序的内存开销,图层的这些优点远远超出它的缺点。所以最好是在禁用图层支持之前测试你app的性能。当你的视图支持图层后,此时该视图被称为layer-backed视图。对于layer-backed视图,系统负责创建底层的图层对象,并保持与视图的同步。所以iOS视图都是支持图层的并且在OS X中的大部分视图也是如此。但是在OS X中,你也可以创建图层托管(layer-hosting view)视图,该视图的图层对象由你来提供。注意:对于layer-backed视图,建议只操作视图而不是图层。iOS中视图仅仅是对图层对象的精简包装,所以任何你对图层的操作通常都会正常工作。但是iOS和OS X平台上操纵图层而不是图层可能不会取得预期的结果。该文档会尽可能的指出这些陷阱并提供一种方式让你可以与它们工作。除了与视图相关的图层,你也可以创建独立的图层对象。你可以嵌入这些独立图层对象到任何其他图层对象中,包括与视图相关的图层。你一般使用图层对象作为具体优化方法的一部分。比如说,如果你想使用相同的图片在多个地方,你可以只加载图片一次,然后将图片和多个独立的图层对象相关联,最后添加这些图层对象到图层树中。每一个图层只会引用源图片而不是尝试在内存中创建自身对图片的拷贝。构建图层对象 图层是Core Animation的核心。图层管理着应用程序的可视内容,图层提供了更改内容样式与可视外观的选项。iOS是自动支持图层的,而如果你是一名OS X开发者,那你必须手动开启图层支持。一旦开启了图层支持,你必须理解如何配置和操控图层以获得你想要的效果。 开启对Core Animation的支持 在iOS app中,Core Animation总是开启的,视图也都是支持图层的。而在OS X中,app必须显示地通过以下方式开启对Core Animation的支持:链接QuartzCore框架(如果iOS app显式地使用了Core Animation则必须链接此框架)。你可选择以下任意一种方式为NSView开启图层支持:u在你的nib文件中,使用View Effect检视面板让视图支持图层。检视面板会对选中的视图和它的子视图显示一个复选框。推荐做法是尽可能的在窗口的内容视图中开启图层支持。u对于使用代码创建的视图,调用视图的setWantsLayer:方法,并传入一个YES值以表明当前的视图是支持图层的。使用上面所提到的方式开启图层支持可创建一个支持图层的视图。系统负责创建视图底层的图层对象,并保持对图层的更新。在OS X中,也可以创建图层托管视图,该视图底层的图层由你的app创建和管理(你不能在iOS中创建图层托管视图)。改变与视图相关联的图层对象支持图层的视图默认会创建一个CALayer实例,一般情况下你可能不需要不同类型的图层对象。但是Core Animation提供了一些不同类型的图层类,每个图层类型都拥有特殊的功能。选择某个图层类可能会提升app的性能或者能以简单的方式支持指定的内容类型。比如CATiledLayer类在显示大图片上将更加高效。改变视图自有的图层类你可以通过覆盖iOS视图中的layerClass方法并返回一个需要的图层类对象。大部分的iOS视图通过创建一个CALayer对象,使用该对象储备视图的内容。使用默认的图层类型是个不错的选择,但在某些情况下,你可能需要使用特定特性的图层对象。比如在下述情况下你需要改变图层的类型:视图的绘图内容是由OpenGL ES实现,此种情况你需要使用CAEAGLLayer对象。特殊的图层让你拥有更强的表现性能。需要利用某些特殊的Core Animation类,比如粒子发射器或者拷贝器。改变一个视图的图层类型非常的简单;所有你需要做得只是覆盖layerClass方法并返回一个你想要替代的类对象。如清单2-1所示,视图调用layerClass方法并使用返回的类为其创建新的图层对象。一旦创建完成,视图的图层对象将不可改变。清单2-1一个iOS视图图层类的指定+(Class) layerClass return CAEAGLLayer class;不同的图层拥有特定的行为Core Animation定义了许多标准的图层类,每一个图层类都有着各自的应用场景。CALayer类是所有图层对象的根类,它定义了所有图层对象必须支持的行为,它也是图层支持的视图的默认图层类型。你可以指定表2-1中的某一个图层类以改变默认的图层类型。类别用途CAEmitterLayer用于实现基于Core Animation粒子发射系统。发射器层对象控制粒子的生成和起源CAGradientLayer用于绘制一个颜色渐变填充图层的形状(所有圆角矩形边界内的部分)CAEAGLLayer/CAOpenGLLayer用于设置需要使用OpenGL ES(iOS)或OpenGL(OS X)绘制的内容与内容储备。CAReplicatorLayer当你想自动生成一个或多个子层的拷贝。复制器为你生成拷贝并使用你指定的属性值以修改复制品的外观和属性。CAScrollLayer用于管理由多个子区域组成的大的可滚动区域CAShaperLayer用于绘制三次贝塞尔曲线。CAShaperLayer对绘制基于路径的形状非常有帮助。因为CAShaperLayer总是生成一个最新的路径。而如果将路径画在图层储备中,一旦图层被缩放,形状就变形了。CATextLayer用于渲染一个无格式或属性文本字符CATransformLayer用于渲染一个真3D的图层层级。而不是由其他图层类实现的2D图层层级。QCCompositionLayer用于渲染一个Quartz组件元素(仅在OS X中有效)提供图层的内容图层是管理app内容的数据对象。图层的内容由包含可视数据的位图构成。使用下述三种方式之一可给提供图层的内容:l直接赋值一个UIImage对象给图层对象contents属性。(这个技术适用于图层内容从不或几乎不改变的情形。)l赋值一个代理给图层,由代理负责绘制图层内容。(该技术适用于图层内容可能偶尔改变,且内容可由外部对象提供,比如视图。)l定义一个CALayer的子类并覆盖类的绘图方法,有覆盖的方法返回图层的内容。(该技术适用于你需要创建自定义图层的子类,或者你想改变图层基本的绘图行为。)你需要为提供图层内容而担心的时刻仅在手动创建图层对象。如果你的app中只包含支持图层的视图。那你不需要担心使用刚刚提到的这些提供图层的方法提供图层内容。支持图层的视图会使用尽可能高效的方式为与之相关的图层提供内容。使用图片为图层提供内容因为一个图层仅是管理位图图片的容器,所以你可以直接赋值一个图片给图层的contents属性。赋值一个图片给图层很简单,只需要指定一张你想显示在屏幕上的具体的图片就可以了。图层将直接使用你提供的图片对象,并不会尝试创建自己的图片拷贝。当你的应用使用相同的图片在多个地方时,该行为可以节省许多内存。你赋值的图片类型必须是CGImageRef类型(在OS X 10.6或之前版本,你也可以赋值一个NSImage对象。)当赋值图片时,记住提供的图片的分辨率要与本地设备的分辨率相匹配。对于Retina显示设备,这可能也需要你去调整图片的contentsScale属性。使用代理提供图层的内容如果图层的内容是动态改变的,你可以使用一个代理对象在需要的时候提供图层并更新内容。图层显示的时候,图层调用你的代理方法以提供需要的内容:如果你的代理实现了displayLayer:方法,实现方法负责创建位图并赋值给contents属性。如果你的代理实现的是drawLayer:inContext:方法,Core Animation创建一个位图,创建一个用于绘制位图的上下文,并调用代理方法填充该位图。你的代理方法所要做的是将内容画在图形上下文上。代理对象必须实现displayLayer:或者drawLayer:inContext方法之一。如果代理对象把这两个方法都实现了,图层只调用displayLayer:方法。覆盖displayLayer:方法在当你的app更倾向于载入或创建想要显示的位图的情况下适用。清单2-3显示了一个实现displayLayer:代理方法的示例代码。在这个例子中,代理使用了一个辅助对象来加载和显示它需要的图片。代理方法根据内部的状态选择哪张图片用于显示。例子中得displayYesImage是一个自定义属性。清单2-3:直接设置图层的内容- (void) displayLayer:(CALayer *)theLayer /检查某些属性状态值 if (self.displayYesImage) /显示Yes图片 theLayer.contents = someHelperObject loadStateYesImage; else /显示No图片 theLayer.contents = someHelperObject loadStateNoImage; 如果你没有预渲染的图片或者辅助对象来创建位图。代理对象可以使用drawLayer:inContext:方法动态的绘制内容。清单2-4显示了一个对drawLayer:inContext方法实现的例子。在该例子中,代理对象使用了固定的宽度和当前的渲染颜色绘制了一个简单的曲线路径。清单2-4:绘制图层上下文- (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext CGMutablePathRef thePath = CGPathCreateMutable(); CGPathMoveToPoint(thePath,NULL,15.0f,15.f); CGPathAddCurveToPoint(thePath, NULL, 15.f,250.0f, 295.0f,250.0f, 295.0f,15.0f); CGContextBeginPath(theContext); CGContextAddPath(theContext, thePath); CGContextSetLineWidth(theContext, 5); CGContextStrokePath(theContext); / Release the path CFRelease(thePath);带有自定义内容并支持图层的视图,你应该去覆盖视图的绘图方法。一个支持图层的视图自动创建它自己的图层代理并实现需要的代理方法,你不应该改变这个配置。相反,你应该实现你视图的drawRect:方法以绘制你的内容。在OS X 10.8和之前的版本中,绘图的另外方法是通过覆盖你视图的wantsUpdateLayer和updateLayer方法提供一个位图。覆盖wantsUpdateLayer并返回YES会引起NSView类调用替换的渲染路径。相对于调用drawRect:方法,视图调用你的updateLayer:方法,方法的实现必须直接赋值一个位图给图层的contents属性。这个AppKit期望你直接设置视图的图层对象内容的一种方案。由子类提供图层的内容如果你实现了一个自定义的图层类,你可以覆盖图层类的绘图方法完成任何绘图的操作。用这种方法生成图层对象的自定义内容是罕见的,但是某些图层却拥有管理显示的内容能力。如CATiledLayer类通过将大图片拆成更小的可管理、可独立渲染的碎片来管理大的图片。因为只有图层知道在某一时刻哪一个碎片需要被渲染,图层会直接管理绘图的行为。当子类化图层类,你可使用下述的两种方式绘制你的图层内容:l覆盖图层的display方法并使用在方法中直接设置图层的contents属性。l覆盖图层的drawInContext:方法并将需要的内容绘制到提供的图形上下文中。选择何种方法依赖于在绘图过程中你需要多少的控制。display方法是更新图层内容的主要入口点,所以覆盖这个方法让你处于完全的过程控制中。覆盖display方法也意味你需要负责contents属性创建CGImageRef对象。如果你只是想绘制内容(或让你的图层管理绘图操作),你可以覆盖drawInContext:方法并让图层为你创建内容储备。调整提供的内容当给图层的contents属性赋值一个图片,图层的contentsGravity属性确定图片如何适合当前的边界。默认情况下,如果一个图片大于小于当前的边界,图层对象缩放图片以适应有效的空间。如果图层的长宽比和图片的长宽比不一致,这会导致图片被扭曲。所以你可以使用contentsGravity属性来确定你的内容以最佳的方式被呈现。你可以向contentsGravity属性赋予的值分为两个分类:l基于位置的引力约束允许你固定你的图片到图层矩形边界的一个特殊的边缘或角落,不会缩放图片。l基于缩放的引力约束允许你伸缩图片使用多个选项之一,某些选项保留长宽比,有些则不保留。图2-1显示了基于位置的引力设置如何影响你的图片。除了kCAGravityCenter约束,每一个约束都将图片固定在图层矩形边界的某个边缘或角落。kCAGravityCenter约束将图片居中在图层中。基于位置的引力约束没有一个选项会缩放图片。所以图片总是和它原始的尺寸一样的情况下被渲染。如果你的图片大于图层的边界,这可能导致部分图片被裁减;如果图片小于矩形边界,如果设置了背景颜色的话,则图片没有覆盖到得区域则显示图层的背景颜色。图2-1基于位置的图层引力约束图2-2显示了基于缩放的引力约束如何影响你的图片。如果图片不是准确匹配图层矩形边界范围内,所有这些约束都会缩放你的图片。这些模式选项之间所不同的是如何处理图片原始的长宽比。一些模式保留原始图片的长宽比,有些则不保留。默认情况是,图层的contentsGravity属性被设置为kCAGravityResize常量值,它是唯一一个不保留图片的长宽比的选项。图2-2基于缩放的图层引力约束使用高分辨率的图片图层并不知道当前设备的分辨率信息。图层只是简单的存储一个指向位图的指针,并用给定的有效像素以最佳的方式显示。如果你赋值一个图片给图层的contents属性,你必须给图层的contentsScale属性设置一个正确的值以告诉Core Animation关于图片的分辨率。默认的属性值为1.0,对于在标准分辨率的屏幕上显示图片是正确的。如果你的图片要在Retina屏幕上显示,该值需要设定为2.0。使用UIScreen mainScreen scale可获取正确的缩放率。仅在直接赋值一副位图给图层才需要改变contentScale属性的值。在UIKit或AppKit中,一个支持图层的视图会被自动设置基于屏幕分辨率的图层缩放因子,并且图层内容由视图管理。在OS X中,基于位置的引力约束影响图片呈现的方式。从NSImage对象选择赋值给图层。因为这些实例不会引起图片的缩放。Core Animation依靠contentsScale属性以最佳的像素密度呈现图片。在OS X中,图层的代理可以实现layer:shouldInheritContentScale:fromWindow:方法,使用该方法响应对缩放因子的改变。可能因为窗口会在标准分辨率和高分辨率屏幕之间移动,AppKit会在窗口分辨率变化时自动调用代理的实现方法。如果代理支持图层的图片分辨率的变化,则此方法返回YES。当需要反映分辨率的变化,该方法会更新图层的内容。调整图层的可视样式和外观图层对象拥有内建的可视装饰,如边框、背景色。你可以使用这些装饰对图层的主内容进行补充。因为这些可视的装饰不需要任何渲染。装饰让图层在一些情况下让图层成为独立的实体成为可能。你只需设置图层的属性,图层自会处理必要的绘图工作,包括动画。图层拥有自己的背景和边框图层除了可以显示基于图片的内容,还可以显示被填充的背景、描边的边框。背景被渲染在图层的内容图片的后方,边框被渲染在内容图片的前方。如图2-3显示。如果图层包含子层,子层也会显示在边框的下方。因为背景颜色是处在图片的后方的,背景会从图片的任何透明的地方透射出来。图2-3给图层添加边框和背景色清单2-5显示了设置图层的边框和背景颜色代码。所有的这些属性都是可动画的。清单2-5:设置图层的背景色和边框myLayer.backgroundColor = NSColor greenColor.CGColor;myLayer.borderColor = NSColor blackColor.CGColor;myLayer.borderWidth = 3.0;注意:你可以将图层的背景设置成任何颜色,包括支持透明的颜色或使用模式图片。使用模式图片时,渲染是由Core Graphics完成,它使用的是标准坐标系统。标准坐标系统和iOS的坐标系统是不一样的。所以,图片在iOS上得渲染结果是颠倒的。可以使用backgroundLayer setTransform:CATransform3DMakeScale(1.0, -1.0, 1.0);解决该问题。如果你将图层的背景颜色设置为不透明。考虑将图层的opaque属性设置为YES。当合成屏幕上的图层时可以提升系能,同时也会消除图层的后备存储管理alpha通道的要求。如果你给图层设置了非零的圆角半径,则不可以将图层标记为不透明类型。图层支持圆角半径你可以通过给图层添加一个圆角半径来创建一个圆角矩形。圆角半径是一个可视的装饰,它遮罩了图层边界矩形的部分区域以允许底层内容的显示。如图2-4所示,因为它包括了应用一个透明蒙版,圆角半径不影响图层的contents属性中得图片,除非masksToBounds属性被设置为YES。然而,圆角半径总是影响图层的背景颜色和边框的绘图方式。图2-4图层的圆角半径为了设置圆角半径,只需要为图层的cornerRadius属性设置一个值。你指定的半径值是以点衡量的,并且圆角半径会应用到图层的四个角上。图层内建支持阴影CALayer类包括若干个配置阴影的属性。阴影让图层更加有深度,好像图层浮起来了。阴影也是另一种装饰。在具体的环境你会发现阴影非常的有用。使用图层你可以控制阴影的颜色,相对于图层内容的位置,透明度以及形状。图层阴影的阴影透明度shadowOpacity默认被设置为0,这有效地隐藏了阴影。改变透明度为非0值将引起Core Animaiton绘制阴影。因为默认情况下,阴影被直接定位在图层的下方。所以你可能为了能够看到阴影而改变阴影的偏移量。你指定的偏移量被应用到图层上使用的是图层的本地坐标系。本地坐标系在iOS和OS X上的表现是不同的。如图2-5所示,图中显示了一个带有偏下偏右阴影的图层。在iOS中,这需要指定一个正值,而在OS X中需要指定一个负值。图2-5给图层设置阴影给一个图层的contents属性赋值一张只有中间部分存在图像四周为透明的图片,并对图层施加阴影,阴影的偏移量为(5,5)。则该阴影只会出现在红色圆的偏右下出现。如果给图层的backgroundColor属性赋值,则此时的阴影就会出现在图层边界的偏右偏下方。图层产生阴影的条件包括设置图层的shadowOffset属性值、shadowOpacity属性值、图层或其子层的contents属性值或者backgroundColor属性值。图2-6四周透明的图片当给图层添加阴影,阴影就是图层内容的一部分,但实际上阴影扩展到了图层边界矩形的外围。结果是,如果你启用了图层的masksToBounds属性,围绕边缘的阴影将被裁减掉。如果你的图层中含有任何透明的内容,这将引起一个古怪的效果,图层下方的阴影部分依然可以看见,但是超出图层边界的部分就没有了。如果既想要阴影又要启用maskToBounds为YES,那么你可以使用两个图层。第一个是包含内容的图层,将该图层的maskToBounds属性设置为YES,然后创建一个相同尺寸且含有阴影效果的第二个图层,最后调用第二个图层的addSublayer方法将第一个图层嵌入到第二个图层中就可以了。 注意:iOS平台上不能给图层添加滤镜给图层添加自定义属性CAAnimation和CALayer类扩展了键值编码以对自定义属性进行支持。你可以使用该行为给图层添加数据并使用你定义的键检索对应的值。你甚至可以给你的自定义属性关联动作,当该属性的值发生变化,对应的动画将会被执行。打印图层支持的视图内容在打印过程中,当需要适应打印环境时,图层将重绘它们的内容。尽管当向屏幕上做渲染的时Core Animation一般是依赖缓存位图。但在打印时它将重绘这些内容。特别情况下,如果支持图层的视图使用drawRect:方法提供图层内容,Core Animation将再次调用drawRect:方法以生成可打印的图层内容。图层的内容动画Core Animation提供的基础设施让轻松创建复杂图层动画变得异常简单,Core Animation扩展了所有拥有图层的视图。例如改变图层框架矩形的尺寸,改变其在屏幕上的位置,应用旋转变换,改变它的透明度。使用Core Animation初始化一个动画和改变属性一样简单,但你也可以显式的创建一个动画并设置动画的参数。用简单的动画表现图层属性的变化你可以以显式或隐式的执行简单的动画。隐式动画使用默认的定时器和动画属性展现动画。而显式动画需要你为动画对象配置一些参数。所以当默认的定时器能够很好的为你服务并且你所要的动画效果不需要太多代码时,隐式动画则非常的适合你。简单的动画包括改变一个图层的属性,以及随着时间的推移,让Core Animation以动画的形式展现这些属性的变化。图层定义了许多会影响图层可视外观的属性。改变这些属性是以动画方式展现外观变化的一种方式。例如将图层的透明度从1.0修改为0.0,这将引起图层的淡出特效,最后图层变为透明。重要:虽然你可以使用Core Animation接口直接让图层支持的视图产生动画,但这样做经常需要额外的步骤。为了触发隐式动画,你所要做的是更新图层对象的属性。当更改的目标是图层树中的图层对象,更改将立即反映到对象上。而图层对象的可视外观并不会立即发生变化,Core Animation将图层对象属性的变化当做是一个触发器,用以创建和安排一个或多个可执行的隐式动画。如清单3-1那样修改图层对象属性,将引起Core Animation为你创建动画对象,动画对象将被安排在下一次更新周期运行。清单3-1隐式动画的方式呈现图层属性的变化theLayer.opacity = 0.0;为了显式地使用动画对象呈现相同的变化,创建一个CABasicAnimation对象并配置该对象的动画参数。在添加动画到图层之前,你可以设置动画的开始值与结束值,改变持续时间,或任何其他动画参数。你指定你想要动画的属性的键路径,接着设置动画参数。为了执行一个动画,你使用addAnimation:forKey:方法将动画对象添加到你想要展现动画的图层上。清单3-2显式动画的方式呈现图层属性的变化CABasicAnimation* fadeAnimation = CABasicAnimation animationWithKeyPath:”opacity”;fadeAnimation.fromValue = NSNumber numberWithFloat:1.0;fadeAnimation.toValue = NSNumber numberWithFloat:0.0;fadeAnimation.duration = 1.0;theLayer addAnimation:fadeAnimation forKey:nil;/改变图层实际的最后数据值theLayer.opacity = 0.0; /记得更新图层树注意:创建一个显示动画,推荐是赋值一个值给动画对象的fromValue属性。如果你没有为该属性指定值,Core Animation将使用图层的当前值作为开始值。如果已经更新了属性作为它的最终值,这将致使fromValue属性值遭到干扰,结果可能并不是你想要的。不同于隐式动画,隐式动画会更新图层对象的值。而显示动画不会更改图层树中的数据。显示动画仅是创建了一个动画。在动画结束之后,Core Animation从图层中移除该动画对象并使用当前的数据值重绘图层。如果你想让显示动画的改变成为永久性的,如你在之前的例子中看到的,你必须更新图层属性。隐式和显示动画都会在当前运行循环周期结束之后开始执行,并且当前的线程必须拥有一个用于执行动画的运行循环。如果你改变了图层的动画属性或者给图层添加了多个动画对象。所有这些动画将会同时被执行。例如将图层移动到屏幕之外的时候添加渐隐动画,这两个动画是同时运行的。然而你可以让动画对象在一个特殊的时间开始执行。用关键帧动画表现一个图层属性的变化尽管一个基于属性的动画是从开始值到结束值改变一个属性,一个CAKeyfarmeAnimation对象让你通过一个目标集合产生动画,在某种程度上,动画可能是线性的或者非线性。一个关键帧动画由一个目标数据值集合组成。每个值的时间应该是可达的。最简单的配置是你使用一个数组指定值和时间。对于一个图层位置的变化,你可以有一个跟随路径的变化。动画对象使用你指定的关键帧并通过在某个值到另一个在给定时间区间内插值的方式构建动画。图3-1显示了一个图层position属性的5秒动画。position是动画跟随一个路径。使用一个CGPathRef数据类型指定的。这个动画的代码如清单3-3所示。图3-1一个图层的postion属性的5秒关键帧动画代码清单3-3创建一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论