美文网首页iOS猛码计划iOS学习笔记2017-3-29iOS动画
iOS动画系列之四:基础动画之平移篇

iOS动画系列之四:基础动画之平移篇

作者: 非典型技术宅 | 来源:发表于2017-02-09 20:27 被阅读2253次

    第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画(上)
    第二篇:iOS动画系列之二:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画。包含了OC和Swift两种源代码(下)
    第三篇:iOS动画系列之三:Core Animation。介绍了Core Animation的常用属性和方法。
    第四篇:CABasic Animation。iOS动画系列之四:基础动画之平移篇
    第五篇:CABasic Animation。iOS动画系列之五:基础动画之缩放篇&旋转篇
    第六篇:iOS动画系列之六:利用CABasic Animation完成带动画特效的登录界面
    第七篇:iOS动画系列之七:实现类似Twitter的启动动画
    第八篇:iOS动画系列之八:使用CAShapeLayer绘画动态流量图
    第九篇:iOS动画系列之九:实现点赞的动画及播放起伏指示器
    第十篇:实战系列:绘制过山车场景

    就像咱们之前说的,所有的动画都是在CALayer上面的。所以在做动画之前我们就要先建立一个CALayer,然后把动画作用在自己创建的这个CALayer上。如果不知道CALyer是啥,可以看看前面的分享哈。传输门:第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画(上)

    最终实现的效果:

    基础动画之平移效果

    1. 基础版的平移

    这里重点是为了演示fromValue/toValue 、 设置layer的Position位置、实现代理方法里面设置position的区别。

    最终实现的效果:

    BasicAnimation.gif

    步骤如下:
    1, 创建CALayer。
    2, 设置CALayer的位置、大小、背景颜色。
    3, 将自定义的CALayer添加到主视图的view上面。
    4, 实例化一个CABasicAnimation对象。
    5, 设置动画属性为平移。
    6, 设置动画的起始位置,从哪里到哪里。
    7,设置动画的持续时间、填充模式、重复次数、设置代理。
    8, 将动画添加到需要作用的CALayer上面。
    9, 实现<CAAnimationDelegate>的代理方法:动画开始时调用的方法、动画结束时调用的方法。

    //遵守动画的代理协议
    @interface STBasicPositionViewController ()<CAAnimationDelegate>
    @property(weak,nonatomic)CALayer * redLayer;
    
    @end
    
    @implementation STBasicPositionViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //创建CALayer
        CALayer *redLayer = [CALayer layer];
        
        //设置位置和大小
        redLayer.position = CGPointMake(200, 200);
        redLayer.bounds = CGRectMake(0, 0, 100, 100);
        
        
        //设置背景颜色
        redLayer.backgroundColor = [UIColor redColor].CGColor;
        
        //把layer添加到UIView的layer上
        [self.view.layer addSublayer:redLayer];
        
        self.redLayer = redLayer;
        
        
        /*------------开始设置动画------------------------*/
        
        //创建动画对象
        CABasicAnimation *basicAni = [CABasicAnimation animation];
        
        //设置动画属性
        basicAni.keyPath = @"position";
        
        //设置动画的起始位置。也就是动画从哪里到哪里
        basicAni.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
        
        //动画结束后,layer所在的位置
        basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];
        
        
        //动画持续时间
        basicAni.duration = 2;
        
        //动画填充模式
        basicAni.fillMode = kCAFillModeForwards;
        
        //动画完成不删除
        basicAni.removedOnCompletion = NO;
        
        //xcode8.0之后需要遵守代理协议
        basicAni.delegate = self;
        
        //把动画添加到要作用的Layer上面
        [self.redLayer addAnimation:basicAni forKey:nil];
     
    }
    
    
    #pragma 实现代理协议的方法
    
    //动画开始的时候调用
    - (void)animationDidStart:(CAAnimation *)anim{
        
        self.redLayer.position = CGPointMake(300, 100);
        
    }
    
    //动画结束的时候调用
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
        
        self.redLayer.position = CGPointMake(300, 400);
    }
    
    
    @end
    

    2. 创建不同速度控制的动画

    上面代码里面我们看到了有一些莫名其妙出来的字符串,例如在设置动画属性的时候出来的:

        //设置动画属性
        basicAni.keyPath = @"position";
    
        //动画填充模式
        basicAni.fillMode = kCAFillModeForwards;
    

    这些属性,在前一篇很枯燥的分享里面有提到。有需要的童鞋可以点进去当作字典翻一下。也没有啥记忆的必要性,需要的时候查一下,需要的时候查一下就好了。传输门:第三篇:iOS动画系列之三:Core Animation。介绍了Core Animation的常用属性和方法。

    速度控制一共有四种模式:

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

    2.1 抽取创建Layer及动画的公共方法

    为了能够偷点懒,所以抽取了公共的方法。可以很方便的创建Layer以及动画。哈哈,本宅胖要是不懒就不会这么胖了。

    #pragma 抽取创建动画及Layer的公共方法
    
    //创建CALayer
    - (CALayer *)createLayerWithPosition:(CGPoint)position backgroundColor:(UIColor *)backgroundColor{
        //创建CALayer
        CALayer *layer = [CALayer layer];
        
        //设置位置和大小
        layer.position = position;
        layer.bounds = CGRectMake(0, 0, 100, 100);
        
        
        //设置背景颜色
        layer.backgroundColor = backgroundColor.CGColor;
        
        //把layer添加到UIView的layer上
        [self.view.layer addSublayer:layer];
        
        return layer;
    }
    
    //创建动画
    - (CABasicAnimation *)createBasicAnimationWithFromValue:(CGPoint)fromValue toValue:(CGPoint)toValue timingFunction:(NSString *)timingFunction{
        //创建动画对象
        CABasicAnimation *basicAni = [CABasicAnimation animation];
        
        //设置动画属性
        basicAni.keyPath = @"position";
        
        //设置动画的起始位置。也就是动画从哪里到哪里
        basicAni.fromValue = [NSValue valueWithCGPoint:fromValue];
        
        //动画结束后,layer所在的位置
        basicAni.toValue = [NSValue valueWithCGPoint:toValue];
        
        //动画持续时间
        basicAni.duration = 2;
        
        //动画重复次数
        basicAni.repeatCount = CGFLOAT_MAX;
        
        //xcode8.0之后需要遵守代理协议
        basicAni.delegate = self;
        
        basicAni.timingFunction = [CAMediaTimingFunction functionWithName:timingFunction];
    
        return basicAni;
    }
    
    

    2.2 创建Layer和动画

    这里我们只创建一个为例。

        //    创建红色线性运动的Layer
        self.redLayer = [self createLayerWithPosition:CGPointMake(0, 150) backgroundColor:[UIColor redColor]];
        [self.redLayer addAnimation:[self createBasicAnimationWithFromValue:CGPointMake(0, 150) toValue:CGPointMake(300, 150) timingFunction:kCAMediaTimingFunctionLinear] forKey:@"linear"];
    

    有朋友可能发现了,为啥添加动画的时候后面的forKey怎么不是之前的nil了呢?
    这里添加一个key值,实际上是为这个动画对象起了一个名字,通过key值,可以很方便的取到这个动画对象

    2.3 移除动画

    动画播放完成之后,我们通过key值将这个动画移除掉。
    这个方法当然是在动画结束的时候调用最合适,不然动画还没放完就移除了岂不是开天窗啦~
    CAAnimationDelegate这个里面的代理方法终于起到作用了。

    //动画结束的时候调用
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
        [self.redLayer removeAnimationForKey:@"linear"];
        
        [self.blueLayer removeAnimationForKey:@"easeIn"];
    
        [self.grayLayer removeAnimationForKey:@"easeOut"];
    
        [self.greenLayer removeAnimationForKey:@"easeInAndEaseOut"];
    
    }
    

    3. Swift版本的部分差异

    Swift版本几乎和OC的一模一样。略有不同的是,swift在加载layer的时候,我们使用了懒加载的方式。也就是在使用的时候才去创建这个layer。

    源代码也放在了码云上面。

        //MARK: - 懒加载
    
        private lazy var redLayer: CALayer = {
            let layer = self.createLayer(position: CGPoint(x: 0, y: 150), backgroundColor: UIColor.red)
            
            return layer
        }()
    

    今天就到这里啦。看样子宏图伟业打算一篇写完的CABasic Animation是没戏啦。下一篇文章写缩放这些的吧。任性的技术宅。哈哈~

    喜欢的话就点个赞呗,或者赏俺点口粮。么么哒~爱你们~

    OC和Swift的下载地址如下:
    https://git.oschina.net/atypical/CABasic-Animation.git

    iOS实践:CABasic-Animation(OC和Swift两版)

    相关文章

      网友评论

      • Andy_Ron:最后的链接地址搞错,搞成之前clock的了
        非典型技术宅:@Andy_Ron 谢谢老大夸赞。么么哒。
        Andy_Ron:@非典型技术宅 动画系列很不错!:smile:
        非典型技术宅:哈哈哈。多谢大大提点。
      • Casablanca1Q84S:你好,我想做一个根据往上滚动的contentoffsetY 让lable 做沿着45度角滑动,这个具体有什么方法呢
        非典型技术宅:valueWithCGPoint:CGPointMake(300, 300) 看到demo里面的这个了嘛?这个就是从(0,0)到(300,300),就是一个斜向下45度角的滑动。如果起点设置成(100,100),终点位置是(150,50)就是斜向上45度角啦。
      • Casablanca1Q84S:可以让沿着45度角滑动吗

      本文标题:iOS动画系列之四:基础动画之平移篇

      本文链接:https://www.haomeiwen.com/subject/uarwittx.html