CALayer层动画详解(一)

作者: z小志 | 来源:发表于2018-04-28 11:40 被阅读35709次

    1、UIView和CALayer的区别

    UIView                                            
    集成UIResponder,可以响应事件;  
    负责对内容的管理;
    位置属性只有frame、bounds、center
    
    CALayer
    只负责内容的创建,绘制
    位置属性只有frame、bounds、center、anchorPoint、position
    

    2、Core Animation 核心动画的特点以及各种动画类的继承关系

    Core Animation来自iOS的QuartzCore.Framework 框架,它具备以下特点:
    1、直接作用于CALayer,而非UIView;
    2、Core Animation执行过程在后台执行,不阻塞主线程
    3、可以利用CALayer绝大多数属性制作高级动画效果
    
    
    CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
    
    属性解析:(红色代表来自CAMediaTiming协议的属性)
    
    duration:动画的持续时间
    
    repeatCount:动画的重复次数
    
    repeatDuration:动画的重复时间
    
    removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
    
    fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
    
    beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
    
    timingFunction:速度控制函数,控制动画运行的节奏
    
    delegate:动画代理
    
    CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation
    
    属性解析:
    
    keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@”position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果
    
    
    
    
    CABasicAnimation是CAPropertyAnimation的子类
    
    属性解析:
    
    fromValue:keyPath相应属性的初始值
    
    toValue:keyPath相应属性的结束值
    
    随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue
    
    如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0)
    
    CAKeyframeAnimation是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
    
    属性解析:
    
    values:就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
    
    path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略
    
    keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的
    
    CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation
    
    
    
    
    CAAnimationGroup
    
    
    CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行
    
    属性解析:
    
    animations:用来保存一组动画对象的NSArray
    
    默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间
    
    CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点
    
    UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果
    
    属性解析:
    
    type:动画过渡类型
    
    subtype:动画过渡方向
    
    startProgress:动画起点(在整体动画的百分比)
    
    endProgress:动画终点(在整体动画的百分比)
    
    

    2、CALayer动画合集

        //位置
        func positionAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "position"
            animation.toValue = CGPoint(x: b_btn.x - 10, y: b_btn.y - 10)
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
    注:fillMode的作用就是决定当前对象过了非active时间段的行为. 比如动画开始之前,动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用.
    
    下面来讲各个fillMode的意义 
    kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 
    kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态 
    kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态 
    kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.
    
        //缩放
        func transformScaleAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "transform.scale.x"
            animation.fromValue = 1.0
            animation.toValue = 0.8
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        //旋转
        func transformRotationAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "transform.rotation"
            animation.fromValue = Double.pi / 2
            animation.toValue = 2.0
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        //位移
        func transformTranslationAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "transform.translation.y"
            animation.toValue = 100
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        
        //圆角
        func transformCornerRadiusAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "cornerRadius"
            animation.toValue = 15
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        //边框
        func transformBorderWidthAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "borderWidth"
            animation.toValue = 15
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        //颜色渐变
        func transformBackgroundColorAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "backgroundColor"
            animation.fromValue = UIColor.green.cgColor
            animation.toValue = UIColor.red.cgColor
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
        
        //淡入淡出
        func transformAlphaAnimation(){
            let animation = CABasicAnimation()
            animation.keyPath = "opacity"
            animation.fromValue = 0
            animation.toValue = 1.0
            animation.duration = 2
            animation.fillMode = kCAFillModeForwards
            animation.isRemovedOnCompletion = false
            b_btn.layer.add(animation, forKey: nil)
        }
    
    
        
    

    3、总结

    位置动画:position、transform.translation.x、transform.translation.y、transform.translation.z
    缩放动画:transform.scale.x、transform.scale.y
    旋转动画:transform.rotation
    颜色动画:backgroundColor、borderColor
    淡入淡出动画:opacity
    高级效果:圆角动画(cornerRadius)、边框动画(borderWidth)、阴影动画(shadowOffset)
    

    相关文章

      网友评论

        本文标题:CALayer层动画详解(一)

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