Core Animation 文档翻译 (第六篇)

?

高级动画技巧


配置属性动画或者关键帧动画的方式是多种多样的。需要同时执行多个动画或者顺序执行多个动画的APP,可以通过高级的方式同步这些动画的timing或者将这些动画绑定在一起。我们也可以使用其他类型的动画对象来创建可视化的transitions和别的有趣的动画效果。

?

过渡动画支持Layer可见性的变化


就像本级标题名字所说一样,一个transition动画对象为Layer创建一个动画性的过渡效果。transistion对象最常用的方法就是以协调的方式让一个Layer动画形式的出现,并让另外一个Layer动画形式的消失。和属性动画不一样,属性动画是改变Layer的一个属性;而transition动画操作layer缓存的image用来创建可视化效应,通过只调整属性这些可视化效应是很难或者几乎不肯能完成的。标准的transition类型可以用来实现渐显、push、移除或者交叉渐隐动画。在OSX上,我们也可以使用Core image filter创建具有特殊效应的transitions,例如擦拭、卷页、波纹或者自定义的其他效果。

为了执行transition动画,我们可以创建CATransition对象并将其添加到相关的Layers。我们在使用transition对象的时候可以指定transition的类型、开始和结束进度点。开始动画前,可以设置开始和结束进度值,这两个值可以让我们的transition动画看起来像从开始值开始,和结束值结束。

代码5-1展示了如何在两个View之间创建push 过渡动画。在这个例子中,myView1和myView2是在同一个父视图上相同的position,并且myView1是可见的在最初。动画效果为myView1想做滑出知道完全隐藏,同时myView2从右边滑入知道完全显示。为了确保在动画的结束时候两个view相应的可见性是正确的,我们需要更新两个view的hidden属性。

?

代码5-1在iOS中两个view之间过度动画

CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;

// Add the transition animation to both layers
[myView1.layer addAnimation:transition forKey:@"transition"];
[myView2.layer addAnimation:transition forKey:@"transition"];

// Finally, change the visibility of the layers.
myView1.hidden = YES;
myView2.hidden = NO;

?

当两个layer都需要相同的过度动画时候,我们可以让他们使用相同的transition对象。使用相同的transition对象也能简化代码。

?

自定义动画时间函数


时间控制函数是动画的重要部分。通过核心动画中CAMediaTiming协议的方法和属性,我们可以为动画指定精确的时间信息。CAAnimation类遵守该协议,因此我们能够指定动画对象的时间信息,隐式动画对象默认封装了这些信息,并优先使用默认的信息。

对于如何理解时间信息和动画时,理解Layer对象和time之间关系是很重要的。每个Layer有他们自己的局部时间,Layer使用自己的局部时间来管理动画时间。通常情况下,两个不同Layer的局部时间是非常接近的,以至于在为这两个Layer指定相同的时间值时,用户也察觉不到。然而,Layer的局部时间能够被它的父Layer和它自身的时间参数所修改。例如,改变Layer的[speed]属性能够引起Layer(和他的sublayer)的动画的duration发生成比例的变化。

为了帮助我们确保时间值是恰当的,CALayer类定义了convertTime:fromLayer: and convertTime:toLayer:方法。我们可以使用这些方法将一个修正的时间值转换为layer的局部时间,或者将一个layer的时间值转换到另外一个Layer。这两个方法涉及到时间相关的属性并返回一个值,我们将这个值可以用于别的layer,这两个方法所涉及到的时间属性也会影响layer的局部时间。代码5-3展示了定期用于获得一个layer的当前局部时间。通过CACurrentMediaTime函数可以获取计算机当前时间,同时可将这个时间用于转换出Layer的局部时间。

?

代码5-3过的Layer的本地时间

CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];

?

一旦我们有了相对于layer局部时间的值,我们可以使用该值去更新动画对象或Layer的时间相关的属性。通过设置这些时间属性,我们可以获得许多有趣的动画行为,这些属性包含以下几种:

  • 使用beginTime属性设置动画的开始时间。通常,动画在下个更新循环开始执行。我们可以使用beginTime参数去延迟几秒动画的开始。将两个动画顺序的关联在一起的方法就是,将一个动画的beginTime和另外一个动画的结束值设置为相同的值。
    如果我们延迟动画的开始时间,我们也应该设置fillModel属性的值为kCAFillModeBackwards。这个模式将会使Layer显示动画的开始值,及时图层树上的Layer对象具有不同的值。如果不设置这个模式,我们将会看到一个到最终值跳跃性的显示在动画开始执行前。其他的模式也是可用的。
  • autoreverses属性将会引发动画以被指定的duration返回动画的开始值。我们将这个属性与repeatCount属性结合起来可以实现在开始值和结束值之间来回做动画。如果autoreversing为YES并为repeatCount属性设置整数值(例如1.0),那么将会引起动画停止在开始值;添加额外的一半动画(例如设置为1.5)将会使得动画停止在结束值的位置。
  • 在组动画中使用timeOffset属性能够让一些动画在组内某些动画之后开始。

?

暂停和重启动画


为了暂停动画,我们可以利用Layer遵守的CAMediaTiming协议,并设置Layer动画的speed为0.0。将speed设置为0将引起动画暂停,直到我们改变这个值为非0值动画才会结束暂停。代码5-4展示了简单的示例关于如何暂停和在暂停后重启动画。

?

5-4暂停和重启Layer的动画


-(void)pauseLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
   layer.speed = 0.0;
   layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer timeOffset];
   layer.speed = 1.0;
   layer.timeOffset = 0.0;
   layer.beginTime = 0.0;
   CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
   layer.beginTime = timeSincePause;
}

?

显示动画让你改变动画的参数


为Layer做的每一个改变必须是transaction的一部分。[CATransaction]类管理动画的创建、将动画组合在一起并将组合的动画以恰当的时间执行。大部分情况下,我们不需要创建自己的transactions。无论何时你为Layer添加显示和隐式动画,核心动画自动创建隐式transaction。然而,我们也能创建显示transactions去更准确的管理这些动画。

使用CATransaction类的方法,我们可以创建和管理transactions。调用begin类方法开始(隐式的创建)新的transaction;调用commit类方法结束transaction。在这两个方法之间调用我们想要作为transaction其中的变化。例如我们使用代码5-5变化layer的两个属性。

?

5-5创建显式的transaction


[CATransaction begin];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];

?

使用transactions最主要的原因就是在transaction的beginTime和commit中间,我们可以改变duration,timing函数和其他参数。我们能够也能够为transaction关联一个完成后执行的block,方便我们的APP能够在这组动画结束后的到通知。改变动画的参数,需要通过修改在使用setValue:forKey:方法修改transaction字典里面对应的key。例如,改变默认duration为10秒,我们应该改变kCATransactionAnimationDuration key,例如代码5-6展示

?

5-6改变动画的默认duration


[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
                 forKey:kCATransactionAnimationDuration];
// Perform the animations
[CATransaction commit];

?

当我们想要为不同的动画集合提供不同的值时,我们可以嵌套transactions。如果想要嵌套,只需要在begin类方法之后再次调用begin方法。每一个begin调用必须和-个commit方法对应。仅当我们提交最后一个最外层的commit方法时,核心动画才会开始相关的动画。

代码5-7展示了两个transaction的嵌套。在这个例子中这个内层的和外层的transaction改变相同的动画参数,但是使用不同的值。

?

5-7嵌套显示的transaction


[CATransaction begin]; // Outer transaction

// Change the animation duration to two seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
                forKey:kCATransactionAnimationDuration];
// Move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);

[CATransaction begin]; // Inner transaction
// Change the animation duration to five seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
                 forKey:kCATransactionAnimationDuration];

// Change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;

[CATransaction commit]; // Inner transaction

[CATransaction commit]; // Outer transaction

?

为动画添加观看者视角


APP可以在三个维度控制Layer;简单的核心动画所展示的Layers是使用了平面投射,本质就是核心动画将3维空间投射到2维平面上了。默认情况下,具有相同尺寸和不同zPosition的Layers看起来像是一样大的,即使他们在Z轴上的坐标是不同的,也就是说我们不能想正常的人眼视角观看这些三维场景。然而,我们可以通过修改Layers的transformation矩阵,加入人眼观看视角。
当调整一个三维场景的视角时,我们需要调整superlayer的sublayerTransform矩阵(superlayer包含这些可被看到的layers),通过调整superlayer能够简化代码的工作量(如果不通过调整superlayer那么我们就需要把相同的视角相关信息应用到所有的子Layer),同时他也确保了视角是正确应用到同级的sublayers上(同级的sublayers可能在不同的平面重叠交叉)。

代码5-8展示了为父Layer创建简单的视角transform。在这种情况下,自定义的人眼视角的变化将会改变沿着Z轴到Layer的距离。通常为了保证Layers以期望的方式,我们为人眼视角指定一个正数值。数值越大看到的越远,数值越小看到的会越细致。

?

代码5-8为父Layer添加视角transform


CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/eyePosition;

// Apply the transform to a parent layer.

?

在类似之上配置了父Layer情况下,我们可以改变任何子Layer的zPosition属性,并观察它们的尺寸(在基于它们到人眼位置)是如何变化的。

原文地址:https://www.cnblogs.com/zhouyubo/p/8422931.html

时间: 2024-10-12 23:02:57

Core Animation 文档翻译 (第六篇)的相关文章

Core Animation 文档翻译 (第一篇)

Core Animation 文档翻译(第一篇)   2018-01-13  星期6 前言:作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前的应用之前有阅读并实践过经典的<iOS核心动画高级技巧>,[其gitbook地址](https://zsisme.gitbooks.io/ios-/content/chapter10/custom-easing-functions.html),然总觉此书的翻译版,对于目前的CoreAnimation 官

iOS Core Animation Advanced Techniques(六): 基于定时器的动画和性能调优

基于定时器的动画 我可以指导你,但是你必须按照我说的做. -- 骇客帝国 在第10章“缓冲”中,我们研究了CAMediaTimingFunction,它是一个通过控制动画缓冲来模拟物理效果例如加速或者减速来增强现实感的东西,那么如果想更加真实地模拟 物理交互或者实时根据用户输入修改动画改怎么办呢?在这一章中,我们将继续探索一种能够允许我们精确地控制一帧一帧展示的基于定时器的动画. 定时帧 动画看起来是用来显示一段连续的运动过程,但实际上当在固定位置上展示像素的时候并不能做到这一点.一般来说这种显

Core Animation 文档翻译 (第八篇)—提高动画的性能

前言 核心动画是提高基于APP动画帧率的好方式,但是核心动画的使用不代表性能的提升的保证.尤其在OSX,当使用核心动画时,我们仍需选择最有效的方式.和所有的性能相关的问题一样,我们应该使用工具时时的评估和跟踪APP的性能,以至于我们能够确保性能是提升而不是退化的. ? 综合的建议和技巧 有以下几种方式能让我们的Layers更有效的实现效果.对于任何优化来说,我们应该在尝试优化前先测量当前代码的性能:根据未优化之前的性能检测结果,能够让我们知道所做的优化是否提升了性能. ? 尽可能的使用不透明的L

Core Animation 文档翻译 (第七篇)—改变Layer的默认动画

前言 核心动画使用action对象实现它的可视化动画.一个action对象是指遵循CAAction协议并定义了Layer相关的动画行为的对象.所有的CAAnimation对象实现了这个协议,无论何时Layer的属性发生变化的时候就会执行对应的action对象(包含CAAnimation对象). 可动画的属性是action的一种类型,我们可以定义几乎所有我们想要的actions,为了达成这个目的,我们就需要定义自己的action并把它们关联到Layer对象 ? 自定义遵守CAAction协议的Ac

Core Animation 文档翻译—附录B(可动画的属性)

前言 ? 许多CALayer和CIFliter的属性都是可动画的.本节附录列出了这些属性默认使用的动画. ? CALayer可动画属性 ? 表B-1展示了CALayer类的可动画属性.针对每个属性此表也列出了对应的默认动画对象的类型,这些动画以隐式的方式执行. ? Table B-1 Layer的属性和他们默认的动画 table th:first-of-type { width: 25%;} 属性 默认动画 anchorPoint 使用默认的隐式CABasicAnimation对象,在表Tabl

Core Animation 文档翻译—附录C(KVC扩展)

前言 ? 关于CAAnimation和CALayer类,核心动画扩展了NSKeyValueCoding协议.这个扩展为一些keys添加了默认值,扩大了封装协议,添加了为CGpoint.CGRect.CGSize和CATransform3D类型的支持. ? KVC支持的集成类 ? CAAnimation和CALayer类是支持KVC的,这意味着我们可以为任意的Keys赋值.即使是CALayer类没有声明的Key属性,我们仍旧可以为它赋值,如下: [theLayer setValue:[NSNumb

IOS开发UI篇--动画(Core Animation)总结

一.简介 IOS 动画主要是指Core Animation框架.官方使用文档地址为:Core Animation Guide.Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架.Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作.你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果.Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速

iOS Core Animation Advanced Techniques-隐式动画

上六章节: 图层树 图层的寄宿图 图层几何学 图层视觉效果 图层变换 专用图层 这篇随笔主要介绍有关图层隐式动画. 隐式动画: 没有指定任何动画类型,而改变了一个属性,Core Animation决定如何并且何时去做动画. 动画执行的事件取决于当前事务的设置: 动画类型取决于图层行为. Core Animation假设屏幕上任何东西都可能做动画,默认动画效果是打开的. 当CALayer的一个 可做动画的 属性 被改变,默认从先前值平滑过渡到新值,而不是立刻显示新值在屏幕上,因此携带了隐式动画.

长路漫漫,唯剑作伴--Core Animation优化

一.简介 当App发展到一定的规模,性能优化就成为必不可少的一点.但是很多人,又对性能优化很陌生,毕竟平常大多时间都在写业务逻辑,很少关注这个.最近在优化自己的项目,也收集了很多资料,这里先浅谈一下使用Instruments中CoreAnimation优化收获的经验以及总结,这是第一篇,后续会更新Timer Profiler,Leaks等其他优化工具的具体用法. 二.准备工作 在性能优化中一个最具参考价值的属性是FPS:全称Frames Per Second,其实就是屏幕刷新率,苹果的iphon