美文网首页
IOS 动画

IOS 动画

作者: Drodly | 来源:发表于2017-05-17 11:13 被阅读0次

    动画 Animation

    CALayer是动画产生的地方,当将动画添加到Layer层的时候,不能直接修改layer的属性

    • CoreAnimation 有两个Layer层次结构 - 模型层树(model layer tree)和表示层树(presentation layer tree)
    - (instancetype)presentationLayer; - 表示层
    - (instancetype)modelLayer; - 模型层
    
    CAAnimation常用的有:
    • CABasicAnimation

    CABasicAnimation的常用属性:

    • duration 动画的持续时间
    • beginTime 指定动画开始的时间,从开始延迟几秒的话,设置为CACurrentMediaTime() + 秒数的方式
    • repeatCount 动画的持续次数
    • repeatDuration 设置动画的时间,在该时间内动画一直执行,不计次数
    • autoreverses 动画结束时是否执行逆动画
    • fillMode 动画在开始和结束时的动画,默认值是KCAFillModeRemoved
      • kCAFillModeForwards 动画开始之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值为YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO
      • kCAFillModeBackwards 将会立即执行动画的第一帧,无论是否设置beginTime属性
      • kCAFillModeBoth kCAFillModeForwards和kCAFillModeBackwards的组合状态
      • kCAFillModeRemoved 动画将在设置的beginTime开始执行(若有设置beginTime属性,则动画立刻执行),而动画执行完成后将会将layer的状态恢复原状
    • timingFunction 设置动画的时间变化
    • fromValue 所要改变属性的起始值
    • toValue 所要改变属性的结束时的值
    • byValue 所要改变属性相同起始值的改变量
      • 注:若将removedOnCompletion设置为false状态,则可能会引起循环引用的问题
      • 原因:由于CAAnimation的delegate使用的Strong类型(强引用类型)
    一般创建动画的时候,会使用到KeyPath的属性

    备注:KeyPath的值

    • positon - 移动位置(CGPoint)
    • opacitu - 透明度(0-1)
    • bounds - 变大与位置(CGRect)
    • bounds.size - 由小变大(CGSize)
    • backgroundColor - 背景颜色(CGColor)
    • cornerRadius - 渐变圆角(任意数值)
    • borderWidth - 改变边框border的大小(图形周围边框,border默认为黑色) (任意数值)
    • contens - 改变layer内容(图片) 若想要达到改变内容的动画效果,则要先在运行之前定义好layer的contents (CGImage)
    • transform.scale - 缩放,放大(0.0-1.0)
    • transform.rotation.x - 旋转动画(翻转,沿着X轴)(M_PI * n)
    • transform.rotation.y - 旋转动画(沿着Y轴)(M_PI * n)
    • transform.rotation.z - 旋转动画(沿着Z轴)(M_PI * n)
    • transform.transiation.x - 横向移动(沿着X轴)(任意数值)
    • transform.transiation.y - 纵向移动(沿着Y轴)(任意数值)

    旋转动画

    #pragma mark - 旋转动画 -
    -(void)setRotateView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 70, 70)];
        animationView.backgroundColor = [UIColor orangeColor];
        
        //将AnimationView添加到self.view上
        [self.view addSubview:animationView];
        //2.创建动画图层
        /**
         3.设置keyPath的常用属性:
         transform.rotation.x  围绕x轴旋转
         transform.rotation.y  围绕y轴旋转
         transform.rotation.z  围绕z轴旋转
         */
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
        
        //4.设置beginTime指定动画开始的时间,从开始延迟几秒的话,设置为CACurrentMediaTime() + 秒数的方式
        basic.beginTime = 0.0;
        
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGPoint:CGPointMake(2*M_PI, 0)];
        
        //6.设置duration动画的持续时间
        basic.duration = 1.5;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        
        /**
         timingFunction   设置动画的时间变化
         kCAMediaTimingFunctionLinear   在整个动画时间内动画都是以相同速度来改变 - 匀速运动
         kCAMediaTimingFunctionEaseIn   动画开始慢,之后加速                 - 加速运动
         kCAMediaTimingFunctionEaseOut  动画开始快,之后减速                 - 减速运动
         kCAMediaTimingFunctionEaseInEaseOut  动画在开始和结束都慢,中间时间段内速度较快
         kCAMediaTimingFunctionDefault  默认动画
         */
        //[basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
        
        //8.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
     
    }
    

    移动动画

    #pragma mark - 移动动画 -
    -(void)SetMoveAnimationView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 120, 70, 70)];
        animationView.backgroundColor = [UIColor orangeColor];
        
        //将AnimationView添加到self.view上
        [self.view addSubview:animationView];
        //2.创建动画图层
        /**3.position    设置内容(eg:UIImage)*/
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"position"];
        
        //4.fromValue所要改变属性的起始值
        basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(40, 240)];
        
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 240)];
        
        //6.设置duration动画的持续时间
        basic.duration = 2;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    

    背景颜色变化动画

    #pragma mark - 背景颜色变化动画 -
    -(void)SetBackgroundColorChangeAnimationView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(100, 50, 70, 70)];
        animationView.backgroundColor = [UIColor orangeColor];
        
        //将AnimationView添加到self.view上
        [self.view addSubview:animationView];
        //2.创建动画图层
        //backgroundColor       设置背景颜色的变化
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
        
        //4.fromValue所要改变属性的起始值
        basic.fromValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);
        
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = (__bridge id _Nullable)([UIColor lightGrayColor].CGColor);
        
        //6.设置duration动画的持续时间
        basic.duration = 2;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
        
    }
    

    内容改变动画

    #pragma mark - 内容改变动画 -
    -(void)SetContantChangeAnimationView
    {
        //1.创建一个View图层
        UIImageView *animationView = [[UIImageView alloc]initWithFrame:CGRectMake(200, 50, 70, 70)];
        animationView.image = [UIImage imageNamed:@"from"];
        
        [self.view addSubview:animationView];
        //2.创建动画图层 contents
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"contents"];
        
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = (__bridge id _Nullable)([UIImage imageNamed:@"to"].CGImage);
        
        //6.设置duration动画的持续时间
        basic.duration = 1.5;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    

    转换圆角动画

    #pragma mark - 圆角变化动画 -
    -(void)SetRadiusView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 310, 70, 70)];
        animationView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:animationView];
        animationView.layer.masksToBounds = YES;
        //2.创建动画图层 contents
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
        
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGPoint:CGPointMake(35, 0)];
        
        //6.设置duration动画的持续时间
        basic.duration = 2;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    

    按比例缩放动画

    #pragma mark - 按比例缩放动画 -
    -(void)SetZoomAnimationView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 400, 70, 70)];
        animationView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:animationView];
        //2.创建动画图层 contents
        /**
         transform.scale 按比例缩放 - 0.8
         transform.scale.x  缩放宽的比例
         transform.scale.y  缩放高的比例
         */
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(0.3, 0)];
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGPoint:CGPointMake(1.3, 0)];
        
        //6.设置duration动画的持续时间
        basic.duration = 2;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    

    按指定大小进行缩放动画

    #pragma mark - 指定大小缩放 -
    -(void)SetAssginZoomView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(120, 400, 70, 70)];
        animationView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:animationView];
        //2.创建动画图层 contents
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"bounds"];
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGRect:CGRectMake(800, 500, 90, 30)];
        
        //6.设置duration动画的持续时间
        basic.duration = 2;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    
    

    设置渐变动画(透明)

    #pragma mark - 透明动画 -
    -(void)SetAlphaAnimationView
    {
        //1.创建一个View图层
        UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(300, 50, 70, 70)];
        animationView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:animationView];
        //2.创建动画图层 contents
        CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"opacity"];
        basic.fromValue= [NSValue valueWithCGPoint:CGPointMake(0.3, 0)];
        //5.设置toValue所要改变属性的结束时的值
        basic.toValue = [NSValue valueWithCGPoint:CGPointMake(1, 0)];
        
        //6.设置duration动画的持续时间
        basic.duration = 0.6;
        
        //7.设置repeatCount动画的持续次数
        basic.repeatCount = INFINITY;
        //8.autoreverses动画结束时是否执行逆动画
        basic.autoreverses = YES;
        //10.将动画添加到图层
        [animationView.layer addAnimation:basic forKey:@"basic"];
    }
    
    
    • CAKeyframeAnimation(关键帧动画)

    常用属性有:

    • values 当path=nil的时候才起作用
    • keyTimes 一个包含若干NSNumber(浮点型值在0.0~1.0之间)对象值得数组,用来区分动画的分割时机
    • calculationMode 计算模式 主要针对的是每一帧的内容来为一个坐标点的情况,也就是对anchorPoint和Position进行的动画
      • kCAAnimationLinear 默认值 自定义控制动画的时间,可以设置keyTimes,表示当关键帧为坐标点的时候,关键帧之间之间直线相连进行插针计算 线性的
      • kCAAnimationDiscrete 离散的 不进行插值计算 所有关键帧之间逐个儿进行显示
      • kCAAnimationPaced 节奏动画,自动计算动画的运动时间,使得动画匀速运行 keyTimes和timingFunctions无效
      • kCAAnimationCubic 对关键帧为坐标点的关键帧进行圆滑曲线相连后进行插值计算 若为曲线形状,可通过tensionValues,continuityValues,biasValues来进行调整自定义,其主要目的是使得运行轨迹变得圆滑,而曲线动画则要设置timingFunctions
      • kCAAnimationCubicPaced 在系统时间内运行的距离相同,keyTimes和timingFunctions无效
    • rotationMode 旋转样式
      • kCAAnimationRotateAuto 根据路径自动旋转
      • kCAAnimationRotateAutoReverse 根据路径自动翻转
    创建一个例子来实现一下
    #pragma mark - CAKeyframeAnimation 核心动画里面的帧动画 -
    -(void)setCAKeyframeAnimationView
    {
        //1.创建View
        UIView * keyFrameAnimation = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
        keyFrameAnimation.center = CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.height/2.0-50);
        //2.创建贝塞尔曲线
        UIBezierPath * bezierPath = [UIBezierPath bezierPathWithOvalInRect:keyFrameAnimation.frame];
        //3.再创建一个存放动画的View
        UIView * animationView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 70, 80)];
        animationView.backgroundColor = [UIColor orangeColor];
        [self.view addSubview:animationView];
        //2.创建帧动画
        CAKeyframeAnimation * keyframe = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        keyframe.duration = 5;
        keyframe.path = bezierPath.CGPath;
        /**
         calculationMode的属性:
         kCAAnimationLinear  默认值 自定义控制动画的时间,可以设置keyTimes,表示当关键帧为坐标点的时候,关键帧之间之间直线相连进行插针计算  线性的
         kCAAnimationDiscrete 离散的 不进行插值计算 所有关键帧之间逐个儿进行显示
         kCAAnimationPaced  节奏动画,自动计算动画的运动时间,使得动画匀速运行 keyTimes和timingFunctions无效
         kCAAnimationCubic  对关键帧为坐标点的关键帧进行圆滑曲线相连后进行插值计算 若为曲线形状,可通过tensionValues,continuityValues,biasValues来进行调整自定义,其主要目的是使得运行轨迹变得圆滑,而曲线动画则要设置timingFunctions
         kCAAnimationCubicPaced  在系统时间内运行的距离相同,keyTimes和timingFunctions无效
         */
        //calculationMode   计算模式 主要针对的是每一帧的内容来为一个坐标点的情况,也就是对anchorPoint和Position进行的动画
        keyframe.calculationMode = kCAAnimationPaced;
        keyframe.repeatCount = INFINITY;
        //设置旋转样式
        /**
         kCAAnimationRotateAuto  根据路径自动旋转
         kCAAnimationRotateAutoReverse  根据路径自动翻转
         */
        keyframe.rotationMode = kCAAnimationRotateAutoReverse;
        [animationView.layer addAnimation:keyframe forKey:@"keyframe"];
        
        //创建CAShapeLayer
        CAShapeLayer * shape = [[CAShapeLayer alloc]init];
        shape.strokeColor = [UIColor lightGrayColor].CGColor;
        shape.fillColor = [UIColor clearColor].CGColor;
        shape.lineWidth = 0.5;
        shape.lineJoin = kCALineJoinRound;
        shape.lineCap = kCALineCapRound;
        shape.path = bezierPath.CGPath;
        [self.view.layer addSublayer:shape];
    }
    
    
    • CATransition(转场动画)

    CATransition的常用属性有:

    • type - 转场动画的类型
      • kCATransitionFade 淡出效果 (支持方向)
      • kCATransitionMoveIn 将新视图移动到旧视图上 (支持方向)
      • kCATransitionPush 用新视图来推出旧视图 (支持方向)
      • kCATransitionReveal 将旧视图移开后再显示新视图 (支持方向)
    • subtype - 转场动画将要去往的方向
      • kCATransitionFromRight 从右侧转场
      • kCATransitionFromLeft 从左侧转场
      • kCATransitionFromTop 从顶部转场
      • kCATransitionFromBottom 从底部转场
    • TimingFunction - 时间函数
    • repeatCount - 重复显示次数
    创建一个例子来实现上述属性:
    #pragma mark - CATransition 主要用于转场动画从一个场景以动画的形式来过渡到另一个场景 -
    -(void)setCATransitionView
    {
        //1、创建显示效果名称的label
        self.textLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
        self.textLabel.center = CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.width/2.0);
        self.textLabel.backgroundColor = [UIColor colorWithRed:88/255.0 green:161/255.0 blue:86/255.0 alpha:1];
        self.textLabel.textColor = [UIColor whiteColor];
        self.textLabel.font = [UIFont systemFontOfSize:16];
        self.textLabel.numberOfLines = 0;
        self.textLabel.textAlignment = NSTextAlignmentCenter;
        [self.view addSubview:self.textLabel];
        
        //创建按钮
        self.clickButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 180, 40)];
        self.clickButton.center = CGPointMake(self.view.frame.size.width/2.0f, self.view.frame.size.height-240);
        self.clickButton.backgroundColor = [UIColor blackColor];
        [self.clickButton setTitle:@"AnimationChange" forState:UIControlStateNormal];
        self.clickButton.titleLabel.textAlignment = NSTextAlignmentCenter;
        [self.clickButton addTarget:self action:@selector(ClickButton) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:self.clickButton];
    }
    //MARK:点击按钮,开始改变转场动画效果
    -(void)ClickButton
    {
        //创建转场动画图层
        CATransition * transition = [CATransition new];
        //设置代理事件
        transition.delegate = self;
        //设置时间
        transition.duration = 1.0;
        //设置时间函数
        /**
         kCAMediaTimingFunctionLinear
         kCAMediaTimingFunctionEaseIn
         kCAMediaTimingFunctionEaseOut
         kCAMediaTimingFunctionEaseInEaseOut
         kCAMediaTimingFunctionDefault 默认
         */
        [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
        
        //设置转场动画类型 默认从第一个开始
        [transition setType:self.animationArray[_index]];
        
        //设置转场动画的方向
        /**
         kCATransitionFromRight  从右侧转场
         kCATransitionFromLeft   从左侧转场
         kCATransitionFromTop    从顶部转场
         kCATransitionFromBottom 从底部转场
         */
        transition.subtype = kCATransitionFromLeft;
        //设置重复次数
        transition.repeatCount = 1;
        //设置键值对
        [transition setValue:@"transitionAnim" forKey:@"anim"];
        //添加到视图
        [self.textLabel.layer addAnimation:transition forKey:@"transition"];
        self.textLabel.text = [NSString stringWithFormat:@"This Animation was %@",self.animationArray[_index]];
    }
    #pragma mark - 实现CAAnimationDelegate方法 -
    -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
    {
        _index = (_index<self.animationArray.count-1)?_index+1:0;
        
        if(flag)
        {
            //创建转场动画
            CATransition * tranAnimation = [CATransition new];
            tranAnimation.delegate = self;
            tranAnimation.duration = 1.0;
            [tranAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
            tranAnimation.type = self.animationArray[_index];
            tranAnimation.subtype = kCATransitionFromLeft;
            tranAnimation.autoreverses = YES;
            tranAnimation.repeatCount = 1;
            [tranAnimation setValue:@"transitionAnim" forKey:@"anim"];
            [self.textLabel.layer addAnimation:tranAnimation forKey:@"transition"];
            self.textLabel.text = [NSString stringWithFormat:@"This Animation was %@",self.animationArray[_index]];
        }
    }
    
    
    • CASpringAnimation(弹簧动画)

    CASpringAnimation的常用属性有:

    • mass 质量,影响图层运动时的弹簧惯性,质量越大,弹簧的拉伸和压缩的幅度越大,动画的速度变慢,并且波动幅度变大
    • stiffness 刚度系数 = 劲度系数/弹性系数 当刚度系数越大的时候,形变所产生的力就越大,运动就越快
    • damping 阻尼系数 阻止弹簧伸缩的系数,阻尼系数越大,停止越快
    • initialVelocity 初始速率,动画的初始速度大小速率为正数时,速度方向与运动方向一致,当速率为负数的时候,速度方向和运动方向相反
    • settingDuration 结算时间,返回弹簧动画到停止时的估算时间,根据当前的动画参数估算通常动画的时间使用结算时间比较准确
    创建一个例子来实现上述属性
    #pragma mark - CASpringAnimation 弹簧动画-
    -(void)setCASpringAnimationView
    {
        //创建label
        self.textLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 200, 50, 30)];
        self.textLabel.backgroundColor = [UIColor redColor];
        [self.view addSubview:self.textLabel];
        
        //创建弹簧动画
        CASpringAnimation * spring = [CASpringAnimation animationWithKeyPath:@"position.x"];
        spring.damping = 5;
        spring.stiffness = 100;
        spring.mass = 1;
        spring.initialVelocity = 0;
        spring.fromValue = [NSValue valueWithCGPoint:CGPointMake(self.textLabel.layer.position.x, 0)];
        spring.toValue = [NSValue valueWithCGPoint:CGPointMake(self.textLabel.layer.position.x+100, 0)];
        spring.autoreverses = YES;
        spring.repeatCount = INFINITY;
        [self.textLabel.layer addAnimation:spring forKey:spring.keyPath];
    }
    

    备注:

    • CABasicAnimation(基础动画)和CAKeyframeAnimation(帧动画)的区别&联系
    • CABasicAnimation可以看做是最多只有两个关键帧的CAKeyframeAnimation

    相关文章

      网友评论

          本文标题:IOS 动画

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