美文网首页CAEmitterLayer 粒子动画
iOS动画-CAAnimation的说明与简单使用

iOS动画-CAAnimation的说明与简单使用

作者: 来不及变坏 | 来源:发表于2021-09-03 19:28 被阅读0次

    CAAnimation是QuartzCore框架里面定义的

    CAAnimation主要是遵循了 CAMediaTiming 协议,拥有了一些动画的属性

    属性 参数类型 备注
    beginTime CFTimeInterval 指定动画开始的时间。(设置动画beginTime为1,动画将延时1秒后开始执行)
    duration CFTimeInterval 动画时长;(默认值为0,但是实际动画默认持续时间为0.25秒)
    speed float 动画执行的速度;(默认值为0,减少它会减慢动画的时间,增加它会加快速度)(设置speed为2时,则动画实际执行时间是duration的一半)
    timeOffset CFTimeInterval 动画时间偏移量;(设置时长3秒动画的timeOffset为1时,动画会从1秒位置执到最后,再执行之前跳过的部分)
    repeatCount float 重复的次数。不停重复设置为 HUGE_VALF
    repeatDuration CFTimeInterval 设置动画的时间。在该时间内动画一直执行,不计次数。
    autoreverses BOOL 动画结束时是否执行逆动画 ,动画从初始值执行到最终值,是否会反向回到初始值;(设置为YES,动画完成后将以动画的形式回到初始位置)
    fillMode NSStrinng 决定当前对象在非动画时间端段的动画属性值,如动画开始之前和动画结束之后
    timingFunction CAMediaTimingFunction 设置动画的速度变化
    fromValue id 所改变属性的起始值
    toValue id 所改变属性的结束时的值
    byValue id 所改变属性相同起始值的改变量
    removedOnCompletion BOOL 动画完成之后是否还原,默认为yes。

    一些常用的animationWithKeyPath值的总结

    使用形式 备注
    transform.scale @(0.8) 比例转化,在所有方向上进行缩放
    transform.scale.x @(0.8) 宽的比例
    transform.scale.y 高的比例 @(0.8)
    transform.rotation.x 围绕x轴旋转 @(M_PI)
    transform.rotation.y 围绕y轴旋转 @(M_PI)
    transform.rotation.z 围绕z轴旋转 @(M_PI)
    cornerRadius 圆角的设置 @(50)
    backgroundColor 背景颜色的变化 (id)[UIColor grayColor].CGColor
    bounds 中心不变,改变大小 [NSValue valueWithCGRect:CGRectMake(0, 0, 50, 50)];
    position 中心改变) [NSValue valueWithCGPoint:CGPointMake(300, 300)];
    contents 改变内容,比如UIImageView的图片 imageAnima.toValue = (id)[UIImage imageNamed:@"name"].CGImage;
    opacity 透明度 @(0.6)
    contentsRect.size.width 横向拉伸缩放 @(0.3)最好是0~1之间的
    contentsRect.size.height 纵向拉伸缩放 @(0.3)最好是0~1之间的

    核心动画Core Animation常用类的继承关系

    动画类 动画特性
    CAMediaTiming 协议;定义了一段动画内用于控制时间的属性的集合
    CAAnimation 抽象类;作为所有动画类型父类,不可直接使用
    CAPropertyAnimation 抽象类;作为基础动画和帧动画的父类,不可直接使用
    CABasicAnimation 基础动画;用于实现单一属性变化的动画
    CAKeyFrameAnimation 关键帧动画;用于实现单一属性连续变化的动画
    CAAnimaitionGroup 组动画;用于实现多属性同时变化的动画
    CATrasition 转场过渡动画;

    CAMediaTiming只有这两个代理方法 顾名思义,一个开始一个结束,CAAnimation实现代理方法不同于其他,CAAnimation不用声明CAAnimationDelegate。直接重写方法即可

    /* Delegate methods for CAAnimation. */
    
    @protocol CAAnimationDelegate <NSObject>
    @optional
    
    /* 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. */
    //动画结束的回调 。flag参数表明了动画是自然结束还是被打断的
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
    
    @end
    

    1.CABasicAnimation
    通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
    2.CAKeyframeAnimation
    Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
    3.CAAnimationGroup
    Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,
    4.CATransition
    这个就是苹果帮开发者封装好的一些动画,

    KeyFrame的意思是关键帧,所谓“关键”就是改变物体运动趋势的帧,在该点处物体将发生运动状态,比如矩形的四个角,抛物线的顶点等。

    values 指明整个动画过程中的关键帧点
    path 与values属性一样,同样是用于指定整个动画所经过的路径的。需要注意的是,values与path是互斥的,当values与path同时指定时,path会覆盖values,即values属性将被忽略。
    keyTimes 是一个数组,用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间为:ti=duration/(5-1),即每条子路径的duration相等,都为duration的1\4。当然,我们也可以传个数组让物体快慢结合。例如,你可以传入{0.0, 0.1,0.6,0.7,1.0},其中首尾必须分别是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7.....
    timeFunctions 这个属性用以指定时间函数,类似于运动的加速度,有以下几种类型。记住,这是一个数组,你有几个子路径就应该传入几个元素
    /** Timing function names. **/

    CA_EXTERN NSString * const kCAMediaTimingFunctionLinear
        CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//默认,匀速执行动画
    CA_EXTERN NSString * const kCAMediaTimingFunctionEaseIn
        CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//浅入,先慢慢加速,后突然停止
    CA_EXTERN NSString * const kCAMediaTimingFunctionEaseOut
        CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//先全速开始,再慢慢减速停止
    CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut
        CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//浅入浅出,先慢慢加速,再慢慢减速
    CA_EXTERN NSString * const kCAMediaTimingFunctionDefault
        CA_AVAILABLE_STARTING (10.6, 3.0, 9.0, 2.0);//效果同KCAMediaTimingFuncationEaseInEaseOut
    

    calculationMode 该属性决定了物体在每个子路径下是跳着走还是匀速走,跟timeFunctions属性有点类似

    /* `calculationMode' strings. */
    
    CA_EXTERN CAAnimationCalculationMode const kCAAnimationLinear
        API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//线性,默认
    CA_EXTERN CAAnimationCalculationMode const kCAAnimationDiscrete
        API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃的出现在各个关键帧上
    CA_EXTERN CAAnimationCalculationMode const kCAAnimationPaced
        API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//平均,keyTimes和Timing functions设置失效
    CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubic
        API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));//平均,同上
    CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubicPaced
        API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));//平均,同上
    
    /* `rotationMode' strings. */
    
    CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAuto
        API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAutoReverse
        API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    

    示例

    实现水波动画

    - (void)drawRect:(CGRect)rect {
         //新建动画数组
        CALayer *animationLayer = [CALayer layer];
        CAAnimationGroup *animationGroup = [self animationGroupAnimations:[self animationArray]];
        CALayer *pulsingLayer = [self pulsingLayer:rect animationGroup:animationGroup];
        //将动画 Layer 添加到 animationLayer
        [animationLayer addSublayer:pulsingLayer];
        
        // 新建缩放动画
        CABasicAnimation *animationTwo = [self oppositeScaleAnimation];
        // 新建一个动画 Layer,将动画添加上去
        CALayer *pulsingLayerTwo = [self pulsingLayer:rect animation:animationTwo];
        //将动画 Layer 添加到 animationLayer
        [animationLayer addSublayer:pulsingLayerTwo];
        [self.layer addSublayer:animationLayer];
    }
    
    - (CALayer *)pulsingLayer:(CGRect)rect animation:(CABasicAnimation *)animation {
        CALayer *pulsingLayer = [CALayer layer];
        pulsingLayer.borderWidth = 0.5;
        pulsingLayer.borderColor = [[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor;
        pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
        pulsingLayer.cornerRadius = rect.size.height / 2;
        [pulsingLayer addAnimation:animation forKey:@"plulsing"];
        return pulsingLayer;
    }
    
    - (CALayer *)pulsingLayer:(CGRect)rect animationGroup:(CAAnimationGroup *)animationGroup {
        CALayer *pulsingLayer = [CALayer layer];
        pulsingLayer.borderWidth = 1;
        pulsingLayer.borderColor = [[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor;
        pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
        pulsingLayer.cornerRadius = rect.size.height / 2;
        [pulsingLayer addAnimation:animationGroup forKey:@"plulsing"];
    
        return pulsingLayer;
    }
    
    - (CAAnimationGroup *)animationGroupAnimations:(NSArray *)array {
        CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
        animationGroup.beginTime = CACurrentMediaTime();
        animationGroup.duration = 2;
        animationGroup.repeatCount = 2;
        animationGroup.autoreverses = YES;//动画结束时是否执行逆动画
        animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];//设置动画的速度变化:淡出
        animationGroup.removedOnCompletion
        return animationGroup;
    }
    
    
    - (NSArray *)animationArray {
        NSArray *animationArray = nil;
        CABasicAnimation *scaleAnimation = [self scaleAnimation];
        CAKeyframeAnimation *borderColorAnimation = [self borderColorAnimation];
        animationArray = @[scaleAnimation, borderColorAnimation];
        return animationArray;
    }
    
    - (CABasicAnimation *)scaleAnimation {
        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
         
        scaleAnimation.fromValue = @1;
        scaleAnimation.toValue = @3;
        return scaleAnimation;
    } 
    
    - (CABasicAnimation *)oppositeScaleAnimation {
        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.fromValue = @1;
        scaleAnimation.toValue = @0.7;
        scaleAnimation.beginTime = CACurrentMediaTime();
        scaleAnimation.duration = 2;
        scaleAnimation.repeatCount = 2;
        scaleAnimation.autoreverses = YES;//动画结束时是否执行逆动画
        scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//设置动画的速度变化:淡出
        return scaleAnimation;
    }
    
    - (CAKeyframeAnimation *)borderColorAnimation {
        CAKeyframeAnimation *borderColorAnimation = [CAKeyframeAnimation animation];
        borderColorAnimation.keyPath = @"borderColor";
        borderColorAnimation.values = @[
            (__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor,
            (__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.3].CGColor,
            (__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.2].CGColor,
            (__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.1].CGColor,
            (__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.0].CGColor];
        borderColorAnimation.keyTimes = @[@0.2,@0.4,@0.6,@0.8,@1
        ];
        return borderColorAnimation;
    }
    

    引用、借鉴

    iOS动画-CAAnimation使用详解https://www.jianshu.com/p/c22918a5e7ca
    简书发表文章格式(MakrDwon使用)https://www.jianshu.com/p/0e63982d7a98

    相关文章

      网友评论

        本文标题:iOS动画-CAAnimation的说明与简单使用

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