iOS - Core Animation 核心动画

简介: 1、UIView 动画具体讲解见 iOS - UIView 动画2、UIImageView 动画具体讲解见 iOS - UIImageView 动画3、CADisplayLink 定时器具体讲解见 iOS - OC NSTimer 定时器CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。

1、UIView 动画

2、UIImageView 动画

3、CADisplayLink 定时器

  • 具体讲解见 iOS - OC NSTimer 定时器

  • CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的 CADisplayLink 对象,把它添加到一个 runloop 中,并给它提供一个 target 和 selector 在屏幕刷新的时候调用。

  • CADisplayLink 使用场合相对专一,适合做 UI 的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer 的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在 UI 相关的动画或者显示内容使用 CADisplayLink 比起用 NSTimer 的好处就是我们不需要再格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

4、CALayer 绘图层

  • 具体讲解见 iOS - CALayer 绘图层

  • 在 iOS 系统中,你能看得见摸得着的东西基本上都是 UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是 UIView。其实 UIView 之所以能显示在屏幕上,完全是因为它内部的一个层。在创建 UIView 对象时,UIView 内部会自动创建一个层(即 CALayer 对象),通过 UIView 的 layer 属性可以访问这个层。当 UIView 需要显示到屏幕上时,会调用 drawRect: 方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了 UIView 的显示。换句话说,UIView 本身不具备显示的功能,是它内部的层才有显示功能。

5、核心动画基本概念

  • Core Animation 中文翻译为核心动画,它是一组非常强大的动画处理 API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。Core Animation 可以用在 macOS 和 iOS 平台。乔帮主在 2007 年的 WWDC 大会上亲自为你演示 Core Animation 的强大:点击查看视频

  • Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程。

  • 要注意的是,Core Animation 是直接作用在 CALayer 上的,并非 UIView。

  • 核心动画 和 UIView 动画 的区别:

    • 核心动画一切都是假象,并不会真实的改变图层的属性值,如果以后做动画的时候,不需要与用户交互,通常用核心动画(转场)。
    • UIView 动画必须通过修改属性的真实值,才有动画效果。

5.1 核心动画继承结构

  • 核心动画继承结构

    animation30

5.2 核心动画使用步骤

  • Xcode6 之前的版本,使用它需要先添加 QuartzCore.framework 和引入对应的框架 <QuartzCore/QuartzCore.h>

  • 开发步骤:

    • 1、首先得有 CALayer。
    • 2、初始化一个 CAAnimation 对象,并设置一些动画相关属性。
    • 3、通过调用 CALayer 的 addAnimation:forKey: 方法,增加 CAAnimation 对象到 CALayer 中,这样就能开始执行动画了。
    • 4、通过调用 CALayer 的 removeAnimationForKey: 方法可以停止 CALayer 中的动画。

5.3 CAAnimation

  • 1、CAAnimation 简介

    • CAAnimation 是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类。

    • 属性说明:

          removedOnCompletion :默认为 YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。
                                如果想让图层保持显示动画执行后的状态,那就设置为 NO,不过还要设置 fillMode 为 kCAFillModeForwards。
          timingFunction      :速度控制函数,控制动画运行的节奏。
          delegate            :动画代理,需要遵守协议 CAAnimationDelegate。
      
          // 来自 CAMediaTiming 协议的属性
          duration       :动画的持续时间。
          repeatCount    :重复次数,无限循环可以设置 HUGE_VALF 或者 MAXFLOAT。
          repeatDuration :重复时间。
          fillMode       :决定当前对象在非 active 时间段的行为。比如动画开始之前或者动画结束之后。
          beginTime      :可以用来设置动画延迟执行时间,若想延迟 2s,就设置为 CACurrentMediaTime()+2,CACurrentMediaTime() 为图层的当前时间。
  • 2、CAAnimation 动画填充模式

    • 设置 fillMode 属性值(要想 fillMode 有效,需要设置 removedOnCompletion = NO)

          kCAFillModeRemoved   :这个是默认值,也就是说当动画开始前和动画结束后,动画对 layer 都没有影响,动画结束后,layer 会恢复到之前的状态。
          kCAFillModeForwards  :当动画结束后,layer 会一直保持着动画最后的状态。
          kCAFillModeBackwards :在动画开始前,只需要将动画加入了一个 layer,layer 便立即进入动画的初始状态并等待动画开始。
          kCAFillModeBoth      :这个其实就是上面两个的合成,动画加入后开始之前,layer 便处于动画初始状态,动画结束后 layer 保持动画最后的状态。
  • 3、CAAnimation 速度控制函数

    • CAMediaTimingFunction 速度控制函数

          kCAMediaTimingFunctionLinear        :线性,匀速,给你一个相对静态的感觉。
          kCAMediaTimingFunctionEaseIn        :渐进,动画缓慢进入,然后加速离开。
          kCAMediaTimingFunctionEaseOut       :渐出,动画全速进入,然后减速的到达目的地。
          kCAMediaTimingFunctionEaseInEaseOut :渐进渐出,动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
  • 4、CAAnimation 动画代理方法

    • CAAnimation 在分类中定义了代理方法

          @interface NSObject (CAAnimationDelegate)
      
          /* Called when the animation begins its active duration. */
      
          // 动画开始执行的时候触发这个方法
          - (void)animationDidStart:(CAAnimation *)anim;
      
          /* Called when the animation either completes its active duration or
           * is removed from the object it is attached to (i.e. the layer). 'flag'
           * is true if the animation reached the end of its active duration
           * without being removed. */
      
          // 动画执行完毕的时候触发这个方法
          - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
      
          @end

5.4 CAPropertyAnimation

  • CAPropertyAnimation 是 CAAnimation 的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:
    • CABasicAnimation
    • CAKeyframeAnimation
  • 属性说明:

        keyPath :通过指定 CALayer 的一个属性名称为 keyPath(NSString 类型),
                  并且对 CALayer 的这个属性的值进行修改,达到相应的动画效果。
                  比如,指定 @“position” 为 keyPath,就修改 CALayer 的 position 
                  属性的值,以达到平移的动画效果。

5.5 CALayer 上动画的暂停和恢复

  • 1、CALayer 上动画的暂停

        // 暂停 CALayer 的动画,自定义方法
        - (void)pauseLayer:(CALayer*)layer {
    
            CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    
            // 让 CALayer 的时间停止走动
            layer.speed = 0.0;
    
            // 让 CALayer 的时间停留在 pausedTime 这个时刻
            layer.timeOffset = pausedTime;
        }
  • 2、CALayer 上动画的恢复

        // 恢复 CALayer 的动画,自定义方法
        - (void)resumeLayer:(CALayer*)layer {
    
            CFTimeInterval pausedTime = layer.timeOffset;
    
            // 让 CALayer 的时间继续行走
            layer.speed = 1.0;
    
            // 取消上次记录的停留时刻
            layer.timeOffset = 0.0;
    
            // 取消上次设置的时间
            layer.beginTime = 0.0;
    
            // 计算暂停的时间(这里也可以用 CACurrentMediaTime() - pausedTime)
            CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    
            // 设置相对于父坐标系的开始时间(往后退 timeSincePause)
            layer.beginTime = timeSincePause;
        }

6、基本动画

  • CABasicAnimation 基本动画,是 CAPropertyAnimation 的子类。

  • 属性说明:

        fromValue :keyPath 相应属性的初始值
        toValue   :keyPath 相应属性的结束值
    
        byValue   :keyPath 相应属性的改变值
  • 动画过程说明:

    • keyPath 内容是 CALayer 的可动画 Animatable 属性。
    • 随着动画的进行,在长度为 duration 的持续时间内,keyPath 相应属性的值从 fromValue 渐渐地变为 toValue。
    • 如果 fillMode = kCAFillModeForwards 同时 removedOnComletion = NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
  • CABasicAnimation 虽然能够做很多基本的动画效果,但是有个局限性,只能让 CALayer 的属性从某个值渐变到另一个值,仅仅是在 2 个值之间渐变。

6.1 平移动画

  • 1、方法 1

        // 说明这个动画对象要对 CALayer 的 position 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
    
        // 动画持续 1.5s
        anim.duration = 1.5;
    
        // position 属性值从 (50, 80) 渐变到 (300, 350)
        anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 80)];
        anim.toValue = [NSValue valueWithCGPoint:CGPointMake(250, 350)];
    
        // 设置动画的代理
        anim.delegate = self;
    
        // 保持动画执行后的状态
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:@"translate"];
    • 第 2 行设置的 keyPath 是 @"position",说明要修改的是 CALayer 的 position 属性,也就是会执行平移动画。

    • 注意第 8、9 行,这里并不是直接使用 CGPoint 这种结构体类型,而是要先包装成 NSValue 对象后再使用。这 2 行代码表示 CALayer 从位置 (50, 80) 移动到位置 (250, 350)。

    • 如果将第 9 行的 toValue 换成 byValue,代表 CALayer 从位置 (50, 80) 开始向右移动 250、向下移动 350,也就是移动到位置 (300, 430)。

          anim.byValue = [NSValue valueWithCGPoint:CGPointMake(250, 350)];
    • 默认情况下,动画执行完毕后,动画会自动从 CALayer 上移除,CALayer 又会回到原来的状态。为了保持动画执行后的状态,可以加入第 15、16 行代码。

    • 第 19 行后面的 @"translate" 是给动画对象起个名称,以后可以调用 CALayer 的 removeAnimationForKey: 方法根据动画名称停止相应的动画。

    • 第 12 行是设置动画的代理,可以监听动画的执行过程,这里设置控制器为代理。需要遵守协议 CAAnimationDelegate,代理需要实现的方法有:

          - (void)animationDidStart:(CAAnimation *)anim {
      
              NSLog(@"%s", __func__);
          }
      
          - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
      
              NSLog(@"%s", __func__);
          }
    • 打印结果为:

          09:11:10.880 CALayerDemo[12721:622836] -[ViewController animationDidStart:]
          09:11:12.419 CALayerDemo[12721:622836] -[ViewController animationDidStop:finished:],position:{50, 80}
    • 实际上,动画执行完毕后,并没有真正改变 CALayer 的 position 属性的值。

    • 效果

      animation32

  • 2、方法 2

        // 说明这个动画对象要对 CALayer 的 transform 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    
        // 动画持续 1.5s
        anim.duration = 1.5;
    
        // 平移,x 轴移动 250,y 轴移动 350,z 轴移动 0
        CATransform3D form = CATransform3DMakeTranslation(250, 350, 0);
        anim.toValue = [NSValue valueWithCATransform3D:form];
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation33

6.2 缩放动画

  • 1、方法 1

        // 说明这个动画对象要对 CALayer 的 bounds 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"];
    
        // 动画持续 2s
        anim.duration = 2;
    
        // 缩放,width 从 100 变为 30,height 从 100 变为 30
        // anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];  // fromValue 可以省略
        anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 30, 30)];
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation34

  • 2、方法 2

        // 说明这个动画对象要对 CALayer 的 transform 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    
        // 动画持续 1.5s
        anim.duration = 1.5;
    
        // 缩放,width 从 100 变为 200,height 从 100 变为 150
        // anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)];
        anim.toValue  = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.0, 1.5, 1.0)];
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation35

  • 3、心跳效果

        // 说明这个动画对象要对 CALayer 的 transform.scale 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    
        // 动画持续 1.0s
        anim.duration = 1.0;
    
        // 缩放倍数
        anim.toValue = @0.5;
    
        // 设置动画执行次数
        anim.repeatCount = MAXFLOAT;
    
        // 保持动画执行后的状态
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
    
        // 添加动画对象到图层上
        [imageView.layer addAnimation:anim forKey:nil];
    • 效果

      animation42

6.3 旋转动画

  • 1、方法

        // 说明这个动画对象要对 CALayer 的 transform.rotation 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    
        // 动画持续 3.5s
        anim.duration = 3.5;
    
        // 缩放倍数
        anim.toValue = @(M_PI_4 * 3);
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation43

  • 2、方法

        // 说明这个动画对象要对 CALayer 的 transform 属性执行动画
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    
        // 动画持续 3.5s
        anim.duration = 3.5;
    
        // 绕着 (0, 0, 1) 这个向量轴顺时针旋转 45°
        // anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0, 0, 0, 1)];
        anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4 * 3, 0, 0, 1)];
    
        // 设置动画执行次数
        anim.repeatCount = MAXFLOAT;
    
        // 保持动画执行后的状态
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
    
        // 添加动画对象到图层上
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation36

7、关键帧动画

  • CAKeyframeAnimation 关键帧动画,是 CAPropertyAnimation 的子类。

  • 与 CABasicAnimation 的区别是:

    • CABasicAnimation 只能从一个数值(fromValue)变到另一个数值(toValue),而 CAKeyframeAnimation 会使用一个 NSArray 保存这些数值。
    • CABasicAnimation 可看做是只有2个关键帧的 CAKeyframeAnimation。
  • 属性说明:

        values   :上述的 NSArray 对象。里面的元素称为 “关键帧” (keyframe)。动画对象会在指定的时间(duration)内,
                   依次显示 values 数组中的每一个关键帧。
        path     :可以设置一个 CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path 只对 CALayer 的 anchorPoint 
                   和 position 起作用。如果设置了 path,那么 values 将被忽略。
        keyTimes :可以为对应的关键帧指定对应的时间点,其取值范围为 0 到 1.0,keyTimes 中的每一个时间值都对应 values 
                   中的每一帧。如果没有设置 keyTimes,各个关键帧的时间是平分的。

7.1 平移动画

  • 1、添加动画关键帧

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation"];
        // CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
        anim.duration = 5.0;
    
        // 动画起始位置,从 position 点出开始
        NSValue *pointVal1 = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    
        // 水平移动 200 - 0,垂直方向不变(0 - 0 = 0)
        NSValue *pointVal2 = [NSValue valueWithCGPoint:CGPointMake(200, 0)];
    
        // 垂直移动 200 - 0,水平位置不变(200 - 200 = 0)
        NSValue *pointVal3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    
        // 水平移动 0 - 200,垂直方向不变(200 - 200 = 0)
        NSValue *pointVal4 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
    
        // 垂直移动 0 - 200,水平位置不变(0 - 0 = 0)
        NSValue *pointVal5 = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    
        // 添加动画关键帧
        anim.values = @[pointVal1, pointVal2, pointVal3, pointVal4, pointVal5];
    
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation44

  • 2、添加动画路径

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation"];
        // CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
        anim.duration = 5.0;
    
        // 添加动画路径
        anim.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 200)].CGPath;
    
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation44

  • 3、划定路径移动

    • DrawView.m

          @interface DrawView ()
      
          @property (nonatomic, strong) UIBezierPath *path;
      
          @end
      
          @implementation DrawView
      
          /// 触摸开始
          - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
      
              // 移除上一个动画
              [self.subviews.firstObject.layer removeAnimationForKey:@"drawAnimation"];
      
              // 获取触摸起始点位置
              CGPoint startPoint = [touches.anyObject locationInView:self];
      
              // 创建路径
              self.path = [UIBezierPath bezierPath];
      
              // 设置起点
              [self.path moveToPoint:startPoint];
          }
      
          /// 触摸移动
          - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
      
              // 获取触摸点位置
              CGPoint touchPoint = [touches.anyObject locationInView:self];
      
              [self.path addLineToPoint:touchPoint];
      
              [self setNeedsDisplay];
          }
      
          /// 触摸结束
          - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
      
              // 添加关键帧动画
      
              CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
              anim.keyPath = @"position";
      
              // 添加动画路径
              anim.path = self.path.CGPath;
      
              anim.duration = 3;
              anim.repeatCount = MAXFLOAT;
              anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
      
              // 给子视图添加核心动画
              [self.subviews.firstObject.layer addAnimation:anim forKey:@"drawAnimation"];
          }
      
          /// 触摸取消
          - (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event {
              [self touchesEnded:touches withEvent:event];
          }
      
          /// 绘图
          - (void)drawRect:(CGRect)rect {
      
              [self.path stroke];
          }
      
          @end
    • ViewController.m

          DrawView *myDrawView = [[DrawView alloc] initWithFrame:self.view.bounds];
          myDrawView.backgroundColor = [UIColor whiteColor];
          [self.view addSubview:myDrawView];
      
          UIImageView *imv = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
          imv.image = [UIImage imageNamed:@"heart2"];
          [myDrawView addSubview:imv];
      • 效果

        animation47

7.2 缩放动画

  • 缩放动画

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    
        anim.duration = 5.0;
    
        // 动画起始大小,1 不缩放
        NSNumber *scaleVal1 = @1;
    
        // 放大 2 倍
        NSNumber *scaleVal2 = @2;
    
        // 不缩放,缩小至原来大小
        NSNumber *scaleVal3 = @1;
    
        // 缩小 0.5 倍
        NSNumber *scaleVal4 = @0.5;
    
        // 不缩放,放大至原来大小
        NSNumber *scaleVal5 = @1;
    
        // 添加动画关键帧
        anim.values = @[scaleVal1, scaleVal2, scaleVal3, scaleVal4, scaleVal5];
    
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation45

7.3 旋转动画

  • 1、旋转动画

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    
        anim.duration = 5.0;
    
        // 动画起始角度,0 不旋转
        NSNumber *rotationVal1 = @0;
    
        // 旋转 M_PI_4 * 1
        NSNumber *rotationVal2 = @(M_PI_4 * 1);
    
        // 旋转 M_PI_4 * 2
        NSNumber *rotationVal3 = @(M_PI_4 * 2);
    
        // 旋转 M_PI_4 * 3
        NSNumber *rotationVal4 = @(M_PI_4 * 3);
    
        // 旋转 M_PI_4 * 4
        NSNumber *rotationVal5 = @(M_PI_4 * 4);
    
        // 添加动画关键帧
        anim.values = @[rotationVal1, rotationVal2, rotationVal3, rotationVal4, rotationVal5];
    
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation46

  • 2、图标抖动

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    
        anim.repeatCount = MAXFLOAT;
    
        NSNumber *rotationVal1 = @(-5 / 180.0 * M_PI);
        NSNumber *rotationVal2 = @(5 / 180.0 * M_PI);
        NSNumber *rotationVal3 = @(-5 / 180.0 * M_PI);
    
        // 添加动画关键帧
        anim.values = @[rotationVal1, rotationVal2, rotationVal3];
    
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation48

8、转场动画

  • CATransition 转场动画,是 CAAnimation 的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。UINavigationController 就是通过 CATransition 实现了将控制器的视图推入屏幕的动画效果。

  • 动画属性:

        type          :动画类型。
        subtype       :动画方向。
        startProgress :动画起点(在整体动画的百分比)。
        endProgress   :动画终点(在整体动画的百分比)。
  • 设置动画类型

        基本型:
            kCATransitionFade      交叉淡化过渡
            kCATransitionPush      新视图把旧视图推出去
            kCATransitionMoveIn    新视图移到旧视图上面
            kCATransitionReveal    将旧视图移开,显示下面的新视图
    
        用字符串表示的类型:
            fade   push   moveIn   reveal   和系统自带的四种一样
            pageCurl               向上翻页效果
            pageUnCurl             向下翻页效果
            rippleEffect           水滴效果
            suckEffect             收缩效果,如一块布被抽走
            cube                   立方体翻滚效果
            alignedCube            立方体翻滚效果
            flip                   翻转效果
            alignedFlip            翻转效果
            oglFlip                翻转效果
            rotate                 旋转
            cameraIrisHollowOpen   相机镜头打开效果
            cameraIrisHollowClose  相机镜头关闭效果
            cameraIris             相机镜头打开关闭效果
    • kCATransitionFade 和 fade 效果,kCATransitionPush 和 push 效果

      animation50animation51

    • kCATransitionMoveIn 和 moveIn 效果,kCATransitionReveal 和 reveal 效果

      animation52animation53

    • pageCurl 效果,pageUnCurl 效果

      animation54animation55

    • rippleEffect 效果,suckEffect 效果

      animation56animation57

    • cube、alignedCube 效果,flip、alignedFlip、oglFlip 效果

      animation58animation59

    • rotate 效果,cameraIris 效果

      animation60animation61

    • cameraIrisHollowOpen 效果,cameraIrisHollowClose 效果

      animation62animation63

  • 设置动画方向

        四种预设,某些类型中此设置无效:
            kCATransitionFromRight
            kCATransitionFromLeft
            kCATransitionFromTop
            kCATransitionFromBottom
  • UIView 实现转场动画方法

        // 单视图
        + (void)transitionWithView:(UIView *)view 
                          duration:(NSTimeInterval)duration 
                           options:(UIViewAnimationOptions)options 
                        animations:(void (^)(void))animations 
                        completion:(void (^)(BOOL finished))completion;
    
        参数说明:
            view:需要进行转场动画的视图
            duration:动画的持续时间
            options:转场动画的类型
            animations:将改变视图属性的代码放在这个 block 中
            completion:动画结束后,会自动调用这个 block
    
        // 双视图
        + (void)transitionFromView:(UIView *)fromView 
                            toView:(UIView *)toView 
                          duration:(NSTimeInterval)duration 
                           options:(UIViewAnimationOptions)options 
                        completion:(void (^)(BOOL finished))completion;
    
        参数说明:
            duration:动画的持续时间
            options:转场动画的类型
            completion:动画结束后,会自动调用这个 block

8.1 添加转场动画

  • 添加转场动画

        @property (weak, nonatomic) IBOutlet UIView *animView;
        @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    
        - (IBAction)btnClick:(id)sender {
    
            static int i = 2;
    
            // 加载图片
            self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"page%d", i]];
    
            i = (i == 2) ? 1 : i + 1;
    
            // 添加转场动画
            CATransition *anim = [CATransition animation];
    
            // 设置动画效果
            anim.type = @"flip";
    
            // 设置动画方向
            anim.subtype = kCATransitionFromLeft;
    
            // 设置动画时间
            anim.duration = 1.0;
    
            // 添加转场动画
            [self.animView.layer addAnimation:anim forKey:nil];
        }

    animation31

    • 效果

      animation49

9、动画组

  • CAAnimationGroup 动画组,是 CAAnimation 的子类,可以保存一组动画对象,将 CAAnimationGroup 对象加入层后,组中所有动画对象可以同时并发运行。

  • 属性说明:

        animations :用来保存一组动画对象的 NSArray。默认情况下,一组动画对象是同时运行的,
                     也可以通过设置动画对象的 beginTime 属性来更改动画的开始时间。

9.1 添加动画组

  • 添加动画组

        // 同时旋转,缩放,平移
        CAAnimationGroup *anim = [CAAnimationGroup animation];
    
        CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        rotation.toValue = @(M_PI_4 * 3);
    
        CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scale.toValue = @0.5;
    
        CABasicAnimation *translation = [CABasicAnimation animationWithKeyPath:@"transform.translation"];
        translation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];
    
        // 添加动画
        anim.animations = @[rotation, scale, translation];
    
        anim.duration = 3.0;
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
    
        // 添加动画组
        [self.myView.layer addAnimation:anim forKey:nil];
    • 效果

      animation64

10、核心动画的使用

目录
相关文章
|
3月前
|
存储 数据建模 iOS开发
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
32 1
|
3月前
|
定位技术 iOS开发
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
19 0
|
6月前
|
编译器 iOS开发 异构计算
读iOS核心动画笔记
读iOS核心动画笔记
24 0
|
7月前
|
iOS开发
iOS 动画绘制圆形
iOS 动画绘制圆形
42 1
|
3月前
|
机器学习/深度学习 PyTorch TensorFlow
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
27 0
|
3月前
|
iOS开发
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
101 0
|
8月前
|
Java API iOS开发
iOS Spring Animation
iOS Spring Animation
76 0
|
11月前
|
API iOS开发
iOS 核心动画
iOS 核心动画
64 0
|
iOS开发
iOS开发-导航栏标题动画
iOS开发-导航栏标题动画
159 0
iOS开发-导航栏标题动画
|
iOS开发
iOS - 个人中心果冻弹性下拉动画
iOS - 个人中心果冻弹性下拉动画
211 0
iOS - 个人中心果冻弹性下拉动画