免费开源的iOS开发学习平台

核心动画CoreAnimation:5-CAKeyframeAnimation关键帧动画

CAKeyframeAnimation关键帧动画,可以在一个values数组中设置针对某个keyPath的多个变化值,从而设计出一个相对复杂的动画播放效果,例如,我们可以设置一个CALayer对象在多个点之间来回移动,或者可以设置多个平移的值。

CAKeyframeAnimation类

CAKeyframeAnimation类与CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个values数组保存多个数值,从而可以实现keyPath指定属性的复杂变化。在values中保存的每个元素都称为一个keyframe,CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation。

@property(nullable, copy) NSArray *values;

注意:保存在values数组中的对象为NSValue类型的对象

另外,我们还可以设计layer的动画运行轨迹path,这里需要用到贝塞尔路径(UIBezierPath),还需要注意的是我们需要把UIBezierPath对象转成CGPathRef类型的对象。

@property(nullable) CGPathRef path;

CAKeyframeAnimation关键帧动画示例

在下方的代码中,创建了一个CAKeyframeAnimation关键帧动画对象,能够实现在3个水平平移值之间相互切换循环播放动画。

  • 在控制器类中添加一个CALayer类的属性,作为动画播放的layer
@interface ViewController ()
@property (nonatomic, strong) CALayer *myLayer;
@end
  • 通过懒加载的方式,设置自定义layer的属性
-(CALayer *)myLayer{
    if (_myLayer == nil) {
        _myLayer = [CALayer layer];
        _myLayer.frame = CGRectMake(140, 100, 100, 100);
        _myLayer.backgroundColor = [UIColor yellowColor].CGColor;
        _myLayer.borderColor = [UIColor redColor].CGColor;
        _myLayer.borderWidth = 4.0;
        _myLayer.cornerRadius = 2.0;
    }
    return _myLayer;
}
  • 添加该自定义layer到控制器视图的layer上
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view.layer addSublayer:self.myLayer];
}
  • 当点击屏幕时,播放平移动画。针对transform.translation.x这个keypath,我们设置了3个平移的数值,分别为0、100、0。由于我们设置了repeatCount为MAXFLOAT,所以这个动画会一直播放。
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //1. 实例化CAKeyframeAnimation对象
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    //2. 设置动画属性
    animation.keyPath = @"transform.translation.x";
    animation.values = @[@0,@100,@0];
    animation.duration = 2.0;
    animation.repeatCount = MAXFLOAT;
    //3. 添加动画对象到一个CALayer类的对象上,播放动画
    [self.myLayer addAnimation:animation forKey:nil];
}

示例代码

https://github.com/99ios/14.4.5