CAKeyframeAnimation(一)使用和属性全面解析

CAKeyframeAnimation

关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值。CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation。

属性解析:

publicvar
values: [AnyObject]?

values: 是关键帧动画最重要的一部分,该值定义了动画执行的行为,它是一个数组,里面的元素理解为”关键帧"(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一关键帧。在添加到数组之前,需要注意:有些对象可以直接添加到数组当中,但是有些对象必须在被添加之前需要进行包装,比如:有些对象需要包装为id类型,而标量数据类型或者结构体必须被包装成为对象,例如:

1:如果属性是 CGRect类型(比如:
bounds and frame 属性),应该包装每一个矩形成为NSValue对象。

2:对于layer的transform属性,需要包装每一个值CATransform3D成为NSValue对象。

3:对于borderColor属性,在被添加到数组之前,需要把CGColorRef数据类型包装成为id类型。

4:对于CGFloat值,包装为NSNumber对象。

5:对于layer的contents属性,使用CGImageRef属性类型。

6:对于CGPoint数据类型,可以使用NSValue对象进行包装,也可以使用CGPathRef对象使用路径进行包装。

publicvar
path: CGPath?

这是一个可选的路径对象,默认是nil.它定义了动画的行为,当path的值非nil时,将覆盖values属性的值,作用与values属性一样(即:如果你设置了path,那么values将被忽略。)对于常速路径动画,
calculationMode应该被设置为 paced。我们可以设置一个CGPathRef\CGMutablePathRef,让层按照这个路径进行动画移动。

publicvar
keyTimes: [NSNumber]?

这是一个可选的轨迹动画的时间数组,数组中的每一个值都是NSNumber对象,并且取值范围在
[0,1]。它定义了动画的步调,数组中的每一个值都与
values中的值一一对应(可以理解为对应的关键帧指定对应的时间点,keyTimes中的每一个时间值都对应values中的每一帧.)。

当keyTimes没有设置的时候,各个关键帧的时间是平分的。默认情况下,一帧动画的播放,分割的时间是动画的总时间除以帧数减去一。你可以通过下面的公式决定每帧动画的时间:总时间/(总帧数-1)。例如,如果你指定了一个5帧,10秒的动画,那么每帧的时间就是2.5秒钟:10/(5-1)=2.5。你可以做更多的控制通过使用
keyTimes 关键字,你可以给每帧动画指定总时间之内的某个时间点。

例子: @[@(0),@(0.2),@(0.5),@(1)];这里面设置的三个的动画时间,假设总时间是10秒,第一段的时间为2秒(0.2
- 0)*10第二段的时间为3秒(0.5-0.2)*10第三段的时间为5秒(1-0.5)*10。

publicvar
timingFunctions: [CAMediaTimingFunction]?

这是一个可选数组,数组中的值是CAMediaTimingFunction类型,如果
values数组定义了n关键帧,那么该数组就需要 n-1个CAMediaTimingFunction值。每一个CAMediaTimingFunction值描述了关键帧从一个值到另一个值之间过渡的步调(即:运动的时间函数)。

kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉

kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开

kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地

kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。

kCAMediaTimingFunctionDefault (默认时间函数)

各值对应图形如下:

publicvar
calculationMode: String 计算动画的时间

该属性是关键帧动画中还有一个非常重要的参数,所谓计算模式:其主要针对的是每一帧的内容为一个座标点的情况,也就是对anchorPoint和
position进行的动画。

当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算

calculationMode目前提供如下几种模式:

kCAAnimationLinear默认值,表示当关键帧为座标点的时候,关键帧之间直接直线相连进行插值计算,该模式提供了最大化控制动画的时间

kCAAnimationDiscrete离散的,不进行插值计算,所有关键帧直接逐个进行显示,该模式使用keyTimess属性,但是忽略timingFunctions属性。

kCAAnimationPaced使得动画均匀进行,而不是按keyTimes设置的或者按关键帧平分时间,此时keyTimes和timingFunctions无效

kCAAnimationCubic 对关键帧为座标点的关键帧进行圆滑曲线相连后插值计算,这里的主要目的是使得运行的轨迹变得圆滑

kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的

注意:如果你想自己处理动画的时间,那么可以使用kCAAnimationLinear or kCAAnimationCubic 模式和keyTimes、timingFunctions属性。keyTimes将定义每一帧所对应的时间,每帧时间的中间值由timingFunctions设置对应的值进行控制。如果没有设置,将使用默认值。

如果动画使用了kCAAnimationCubic计算模式,那么下面这些属性将控制插值方案。每一帧都有可能与拉力,连续性,偏斜等值相关,这些值得范围是[-1, 1] (this defines a Kochanek-Bartels
spline, see http://en.wikipedia.org/wiki/Kochanek-Bartels_spline).

public var
tensionValues: [NSNumber]?   该值控制着曲线的紧密度(正值将越紧,负值将越宽松)

publicvar
continuityValues: [NSNumber]? 该值控制片段之间的链接(正值将有锋利的圆角,负值将是倒立的圆角)

publicvar
biasValues: [NSNumber]?   该值定义了曲线发生的地点(正值将在在控制点前移动曲线,负值将在控制点后移动)

上面每一个数组,第一个值将定义第一个控制点正切的行为,第二个值将是第二个切点。如果没有具体的值,默认为0.

publicvar
rotationMode: String? 定义是否沿着路径旋转匹配对象动画路径切线,值可能为kCAAnimationRotateAuto和kCAAnimationRotateAutoReverse.默认是nil.如果没有路径对象,设置该属性值将无效,kCAAnimationRotateAutoReverse为了匹配正切将添加180°.

下面是官方文档的部分翻译内容:

基本的动画对象改变属性是从一个开始值到结束值。而一个CAKeyframeAnimation对象能够让你设置一系列值来进行动画并且可以设置对应值所进行的动画时间,通过简单的设置关键帧和关键帧时间两个数组即可。为了改变layer的位置,我们也可以使用路径进场动画。

图 3-显示了5秒的layer’sposition 属性动画效果,位置的动画使用了路径,路径是一个具体的CGPathRef数据类型。动画部分的代码为Listing
3-3
.

Figure 3-1  5-second
keyframe animation of a layer’s position property

Listing 3-3  Creating
a bounce keyframe animation

// create a CGPath that implements two arcs (a bounce)
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,74.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,74.0,500.0,
                      320.0,500.0,
                      320.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,320.0,500.0,
                      566.0,500.0,
                      566.0,74.0);

CAKeyframeAnimation * theAnimation;

// Create the animation object, specifying the position property as the key path.
theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
theAnimation.path=thePath;
theAnimation.duration=5.0;

// Add the animation to the layer.
[theLayer addAnimation:theAnimation forKey:@"position"];

停止正在进行的动画

动画一般都是正常进行直到他们完成,但是我们也能够提前停止动画,如果需要提前停止动画,我们可以使用下列方法之一:

1)去除layer上单一的动画对象,调用layer的removeAnimationForKey:方法去除动画对象,该方法对应layer的addAnimation:forKey:方法添加动画对象,key值不能够为nil,并且相同。

2)去除layer上所有的动画对象,通过调用layer的removeAllAnimations方法,该方法将立马去除所有当前执行的动画并且重绘当前layer的状态信息。

注意:不能够直接去除隐式动画。

当去除layer上的动画对象时,Core
Animation将使用layer当前的values进行重绘,因为当前值是动画的最后值,这能够导致layer显示突然的跳动,如果想要layer的显示保持最后一帧动画,你能够使用对象的图层树来获取最终的值,并设置layer树对象。对于更多暂时停止动画,可以看Listing5-4.

多动画部分同时进行

如果想要对layer对象同事使用多个动画,我们能够使用CAAnimationGroup对象,使用群组动画对象能够非常方便的管理多个动画对象。设置Timing
and duration属性值将取代当个动画对应的属性值。Listing 3-4将告诉我们如何使用组合与border-relate的动画。

Listing 3-4  Animating
two animations together

// Animation 1
CAKeyframeAnimation* widthAnim = [CAKeyframeAnimationanimationWithKeyPath:@"borderWidth"];
NSArray* widthValues = [NSArrayarrayWithObjects:@1.0, @10.0, @5.0, @30.0, @0.5, @15.0, @2.0, @50.0, @0.0, nil];
widthAnim.values = widthValues;
widthAnim.calculationMode = kCAAnimationPaced;

// Animation 2
CAKeyframeAnimation* colorAnim = [CAKeyframeAnimationanimationWithKeyPath:@"borderColor"];
NSArray* colorValues = [NSArrayarrayWithObjects:(id)[UIColorgreenColor].CGColor,
                        (id)[UIColorredColor].CGColor, (id)[UIColorblueColor].CGColor,  nil];
colorAnim.values = colorValues;
colorAnim.calculationMode = kCAAnimationPaced;

// Animation group
CAAnimationGroup* group = [CAAnimationGroupanimation];
group.animations = [NSArray arrayWithObjects:colorAnim, widthAnim, nil];
group.duration = 5.0;

[myLayer addAnimation:group forKey:@"BorderChanges"];

更高级的方式对于组合动画可以使用事务对象,事务将通过更多便利的方式来创建嵌套动画并且可以为每一个赋值不同的动画参数。对于更多详情的事务信息,可以看 Explicit
Transactions Let You Change Animation Parameters
.

检测动画

Core Animation支持检测动画的开始和结束,这些通知是非常有利于处理与动画相关的任务。例如:你可能使用开始的通知设置一些相关的开始信息而且使用结束通知来信息处理这些状态信息。

这里有两种不同的方式通知有关于动画的状态:

1)添加block到当前事务(transaction)当中使用setCompletionBlock:方法,当所有的动画在事务中完成,transaction将执行你的block。

2)设置代理对象,实现代理方法animationDidStart: and animationDidStop:finished:

如果你想束缚两个动画,实现单一个动画完成又立马开始另外一个动画,并且不想使用动画通知操作。那么可以使用beginTime属性,这是每一个动画开始的时间,为了实现一个动画完成又立马开始另外一个动画,可以设置第二个动画的开始时间是第一个动画的结束时间。对于更多的信息可以看Customizing
the Timing of an Animation
.

时间: 2024-09-28 02:25:14

CAKeyframeAnimation(一)使用和属性全面解析的相关文章

如何在App中实现朋友圈功能之五点赞、评论属性详细解析——箭扣科技Arrownock

如何在App中实现朋友圈功能 之五 点赞.评论属性详细解析 快速查看评论和点赞数量: 当我们创建一个墙贴后,这个墙贴会自动带有评论数量commentCount.赞数量likeCount.讨厌数量dislikeCount三个属性. 当有用户对这个墙贴进行了评论,该墙贴的commentCount属性会自动增长,无需开发者来手动操作实现. 如果用户建立的Like中like=true,那么likeCount会自动增长,反之,dislikeCount会自动增长. 如果用户把评论删除了,或者是把点赞撤销了,

Method Resolve Order (MRO) - 类对象属性的解析顺序

Method Resolve Order (MRO) - 类对象属性的解析顺序 Python 支持多重继承, 此时就需要解决按照何种顺序来解析属性的问题.类的继承关系在一个特殊的类属性中指定(__mro__).这个属性的作用是按照序列出类及其超类, python 会按照这个顺利搜索方法.任何实现了多重继承的语言都要处理潜在的命名冲突问题,这种冲突由不相关的父类实现的同名方法所引起的,称为'菱形问题'. 举个例子, 1 class A(list): 2 def disp(self): 3 prin

C# Chart各个属性详细解析、应用

Chart笔记 前台页面代码: <form id="form1" runat="server"> <div> <asp:Chart ID="Chart1" runat="server"> <Series> <asp:Series Name="Series1"> </asp:Series> <asp:Series Name=&quo

NIO中Buffer的重要属性关系解析

Buffer 是java NIO中三个核心概念之一 缓存, 在java的实现体系中Buffer作为顶级抽象类存在 简单说,Buffer在做什么? 我们知道,在java IO中体系中, 因为InputStream和OutputStream是抽象类,而java又不可以多重继承,于是任何一个流要么只读,要么只写.而无法完成同时读写的工作 于是: Buffer来了 NIO中,对数据的读写,都是在Buffer中完成的,也就是说,同一个buffer我们可以先读后写, 它底层维护着一个数组,这个数组被三个重要

Flex布局部分属性困惑解析

开始 最近研究一个框架,刚好里面也实现了flex布局的算法,虽然平时也用到flex做一些简单的布局,但是深入到算法实现的时候,发现自己对flex某些概念倒是没那么清晰,立马谷歌把几个flex涉及的属性都好好理清一下,权当一个自我梳理. main-axis和cross-axis main其实跟flex-direction这个属性相当有关系,关系如下图:根据flex-direction的值不同,main-axis方向相应也不同.既然有方向这个概念,这个时候justify-content属性(just

如何实现一个Java Class 解析器

原文出处: tinylcy 最近在写一个私人项目,名字叫做ClassAnalyzer,ClassAnalyzer的目的是能让我们对Java Class文件的设计与结构能够有一个深入的理解.主体框架与基本功能已经完成,还有一些细节功能日后再增加.实际上JDK已经提供了命令行工具javap来反编译Class文件,但本篇文章将阐明我实现解析器的思路. Class文件 作为类或者接口信息的载体,每个Class文件都完整的定义了一个类.为了使Java程序可以"编写一次,处处运行",Java虚拟机

javaweb学习总结九(xml解析以及调整JVM内存大小)

一:解析XML文件的两种方式 1:dom,document object model,文档对象模型. 2:sax,simple API for XML. 3:比较dom和sax解析XML文件的优缺点 a:dom 优点:dom解析方式会把xml文件加载到内存中,按照xml的结构解析成dom树,元素.文本.属性都会解析成对象,方便进行增删改查. 缺点:如果xml文件比较大,加载文件内存压力大. b:sax 优点:sax解析方式是一行一行的读取xml文件,所以不会造成内存压力. 缺点:不能进行增删改的

Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解

原创整理不易,转载请注明出处:Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解 代码下载地址:http://www.zuidaima.com/share/1772661373422592.htm 本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifi

解析数据存储MySQL

为了适应不同项目对不同感兴趣属性的解析存储,数据存储结构采用纵向的属性列表方式,即一个url页面多个属性存储多条记录方式,并且按照text,html,data,num几大典型类型分别对应存储. 创建UTF-8字符集的nutch数据库,并执行表初始化脚本,参考DDL: CREATE TABLE `crawl_data` ( `url` varchar(255) NOT NULL, `code` varchar(255) NOT NULL, `name` varchar(255) DEFAULT N