美文网首页
iOS 开发核心动画Core Animation(附demo)

iOS 开发核心动画Core Animation(附demo)

作者: 本本的开心牧场 | 来源:发表于2018-09-20 16:11 被阅读0次

    最近在研究iOS动画,iOS中添加动画的方法:UIView的简单动画,layer的隐式动画,还有Core Animationpop等....

    简单介绍

    • Core Animation,译为核心动画,是苹果提供的非常强大的动画处理API.
    • Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
    • Core Animation是作用于CALayer上的动画,每一个继承与UIView的子类都有一个layer属性,可以通过这个layer来为更改相应view的形式,或者做动画。

    Core Animation类的继承关系图


    CAAnimation

    注意2个属性

    timingFunction 动画速度
    kCAMediaTimingFunctionLinear  线性,匀速
    kCAMediaTimingFunctionEaseIn  渐进,逐渐进入,然后加速完成
    kCAMediaTimingFunctionEaseOut 渐出,动画全速进入,然后缓慢完成
    kCAMediaTimingFunctionEaseInEaseOut  渐进渐出
    
    removedOnCompletion
    默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。
    如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode
    

    CAMediaTiming

    CAMediaTimingCAAnimation遵守的协议
    CAMediaTiming中的属性

    beginTime   动画的开始时间(如果超过的duration,那么动画不会开始)
    duration    动画的持续时间
    speed       动画的速度
    repeatCount 重复次数,默认为0,无限重复可以设置为HUGE_VALF或者MAXFLOAT
    repeatDuration 动画重复时间,默认为0
    fillMode     决定当前对象在非active时间段的行为。(要想fillMode有效,最好设置removedOnCompletion = NO)
    
    fillMode类型:
         kCAFillModeRemoved     这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
         kCAFillModeForwards    当动画结束后,layer会一直保持着动画最后的状态
         kCAFillModeBackwards   在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
         kCAFillModeBoth        这个其实就是上面两个的合成,动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
    
    

    3.Core Animation使用的三步骤
    1.创建动画.
    2.设置相关属性.
    3.将动画添加到某个layer.

    - (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;
    

    也可以移除动画

    - (void)removeAnimationForKey:(NSString *)key;
    

    CABasicAnimation 基本动画

    通过设置fromValuetoValue 传入指定的keyPath 可以以动画的形式改变控件的一些属性 如平移,缩放,旋转

    fromValue   指定属性(keyPath)开始的值
    toValue     指定属性结束时的值
    byValue    在原有的值上改变
    

    示例代码

    //1.创建动画.
     CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    //设置相关属性
     basicAnimation.keyPath = @"position.x";
     basicAnimation.byValue = @(10);
    // 不希望回到原来的位置
     basicAnimation.fillMode = kCAFillModeBoth;
     basicAnimation.removedOnCompletion = NO;
        //将动画添加到某个layer.
     [self.button.layer addAnimation:basicAnimation forKey:nil];
    

    CAKeyframeAnimation 关键帧动画

    CABasicAnimation 不同的是CAKeyframeAnimation会使用一个NSArray保存一组关键帧,而且通过绘图来指定路径。而CABasicAnimation只能从一个数值(fromValue)变换成另一个数值(toValue
    通过数组的形式

     CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
     NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
     NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(150, 200)];
     NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(150, 400)];
     NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
     NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
     NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, 200)];
     keyframeAnimation.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
     keyframeAnimation.duration = 3.f;
     keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
     keyframeAnimation.delegate = self;
     [self.customView.layer addAnimation:keyframeAnimation forKey:nil];
    

    通过设置路径的形式

    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
            keyframeAnimation.path = path.CGPath;
            keyframeAnimation.duration = 2.0f;
            
            [self.customView.layer addAnimation:keyframeAnimation forKey:nil];
    

    CAAnimationGroup 组动画

    CAAnimationGroup可以保存一组动画对象(比如可以把前面的2中动画结合起来),将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

        CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
        NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(150, 200)];
        NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(150, 400)];
        NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
        NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
        NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width, 200)];
        keyframeAnimation.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
        keyframeAnimation.duration = 4.f;
        keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
        
    //    缩放
        CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        anima.fromValue = [NSNumber numberWithFloat:0.8f];
        anima.toValue = [NSNumber numberWithFloat:2.0f];
        
    //    旋转动画
        CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        anima2.toValue = [NSNumber numberWithFloat:M_PI*4];
        
        //组动画
        CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
        groupAnimation.animations = [NSArray arrayWithObjects:keyframeAnimation,anima,anima2, nil];
        groupAnimation.duration = 4.f;
        [self.customView.layer addAnimation:groupAnimation forKey:nil];
    

    CATransition 过渡动画

    • 能够为层提供移出屏幕和移入屏幕的动画效果
      基本属性
    type:动画过渡类型
    subtype:动画过渡方向
    startProgress:动画起点(在整体动画的百分比)
    endProgress:动画终点(在整体动画的百分比)
    
    type :动画类型
    基本效果:
          kCATransitionFade        渐入渐出效果
          kCATransitionMoveIn      移入效果
          kCATransitionPush        推入效果
          kCATransitionReveal      推出效果
    
    私有API
              cube                   3D方块
              suckEffect             三角
              rippleEffect           水波
              pageCurl               上翻页
              pageUnCurl             下翻页
              oglFlip                上下翻转
              cameralrisHollowOpen      镜头快门开
              cameralrisHollowClose     镜头快门关
    

    示例

     CATransition *transition = [CATransition animation];
     transition.type = kCATransitionFade;//设置动画的类型
     transition.subtype = kCATransitionFromRight; //设置动画的方向
     //anima.startProgress = 0.3;//设置动画起点
     //anima.endProgress = 0.8;//设置动画终点
     transition.duration = 1.0f;
        
     [self.imageView.layer addAnimation:transition forKey:nil];
    

    最后有一点我还是得说一下,虽然看上去核心动画改变的控件的属性(如frame,scale),但是实际控件的真实属性并未被改变,他只是作用在layer上的。

    demo传送门

    相关文章

      网友评论

          本文标题:iOS 开发核心动画Core Animation(附demo)

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