CAKeyframeAnimation是CAPropertyAnimation的一个子类,与CABasicAnimation的主要区别在于:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation则使用一个NSArray来保存这些数值,从而实现CALayer的某一属性按照一串数值进行动画。这种方式就像制作动画时逐帧制作一样。

CAKeyframeAnimation具有以下几个关键属性:

1. values:这是一个NSArray对象,其中包含一系列称为“关键帧”(keyframe)的元素。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧。

2. path:设置一个CGPathRef或CGMutablePathRef的路径对象,默认为nil。当设置了path后,CALayer会沿着该路径移动。需要注意的是,path仅对CALayer的anchorPoint(锚点)和position(位置)起作用。如果设置了path,那么values将被忽略。

3. keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0。keyTimes中的每一个时间值都对应values中的每一帧。当keyTimes没有设置时,各个关键帧的时间是平分的。需要注意的是,CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation。

总之,CAKeyframeAnimation通过使用values、path和keyTimes等属性,实现了更为灵活的动画效果。

. 创建5个关键帧的点对象

2. 定义p1、p2、p3、p4、p5这5个关键帧的CGPoint值

3. 将这些关键帧放入数组中,使用NSValue结构体类型转化成对象

4. 创建CAKeyframeAnimation动画对象,设置keyPath属性为"position"

5. 为Values属性赋值,将之前创建的关键帧数组设置为动画的values属性

6. 设置动画完成后保持最新状态,即不删除动画对象

7. 设置动画的持续时间为4.0秒

8. 设置动画的定时函数属性为EaseInEaseOut缓动函数

9. 将动画委托设置为当前视图控制器对象

10. 将创建好的动画添加到当前视图的图层上

CAMediaTimingFunction是一种用于在动画过程中改变动画速度的函数,它决定了动画运行的节奏。以下是一些常见的CAMediaTimingFunction类型及其特点:

1. kCAMediaTimingFunctionLinear:线性,即匀速。

2. kCAMediaTimingFunctionEaseIn:先慢后快。

3. kCAMediaTimingFunctionEaseOut:先快后慢。

4. kCAMediaTimingFunctionEaseInEaseOut:先慢后快再慢。

5. kCAMediaTimingFunctionDefault:实际效果是动画中间比较快。

需要注意的是,当上述预置不能满足需求时,可以使用以下两种方法自定义timingFunction:

1. 使用+ (id)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;方法创建一个新的CAMediaTimingFunction对象。

2. 使用- (id)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;方法初始化一个CAMediaTimingFunction对象。

此外,还可以通过Path方式来实现类似的效果。

```objectiveCAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

CGMutablePathRef myPath = CGPathCreateMutable();

// 将路径的起点定位到(50, 120)

CGPathMoveToPoint(myPath, NULL, 50.0, 120.0);

// 添加5条直线的路径到myPath中

CGPathAddLineToPoint(myPath, NULL, 60, 130);

CGPathAddLineToPoint(myPath, NULL, 70, 140);

CGPathAddLineToPoint(myPath, NULL, 80, 150);

CGPathAddLineToPoint(myPath, NULL, 90, 160);

CGPathAddLineToPoint(myPath, NULL, 100, 170);

// 添加4条曲线路径到myPath中

CGPathAddCurveToPoint(myPath,NULL,50.0,275.0,150.0,275.0,70.0,120.0);

CGPathAddCurveToPoint(myPath,NULL,150.0,275.0,250.0,275.0,90.0,120.0);

CGPathAddCurveToPoint(myPath,NULL,250.0,275.0,350.0,275.0,110.0,120.0);

CGPathAddCurveToPoint(myPath,NULL,350.0,275.0,450.0,275.0,130.0,120.0);

//以"position"为关键字创建实例

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

[animation setAutoreverses:YES];

//设置path属性

animation.path = myPath;

//释放路径

CGPathRelease(myPath);

animation.removedOnCompletion = NO;

animation.fillMode = kCAFillModeForwards;

animation.duration = 4.0;

animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

animation.delegate=self;

[self.myView.layer addAnimation:animation forKey:nil];

```

关键帧动画中的calculationMode属性用来设定关键帧中间的值是怎么被计算的。目前提供如下几种模式:kCAAnimationLinear、kCAAnimationDiscrete、kCAAnimationPaced、kCAAnimationCubicPaced 。