• Core Animation笔记(动画)


    一.隐式动画

    layer默认开启隐式动画

    禁用隐式动画

     [CATransaction setDisableActions:true];

    设置隐士动画时间

     //默认0.25s
        [CATransaction setAnimationDuration:3.0];

        //新启一个事务,防止对同一时间其他隐士动画产生影响   

     
        [CATransaction begin];
        //默认0.25s
        [CATransaction setAnimationDuration:3.0];
        //动画完成调用块 0.25s后调用 完成快是在事务提交之后才执行的 所以使用默认的时间0.25,后面再执行此方法是3秒后才调用
        [CATransaction setCompletionBlock:^{
            self.colorLayer.affineTransform = CGAffineTransformRotate(self.colorLayer.affineTransform, M_PI/4);
        }];
        //动画缓冲  默认为kCAMediaTimingFunctionLinear
      /*

        kCAMediaTimingFunctionEaseIn
        kCAMediaTimingFunctionEaseOut
        kCAMediaTimingFunctionEaseInEaseOut
        kCAMediaTimingFunctionDefault
    */
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
      
        CGFloat red = arc4random()*1.0/ INT_MAX;
        CGFloat green = arc4random()*1.0/ INT_MAX;
        CGFloat blue = arc4random()*1.0/ INT_MAX;
    
        // 
        self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
      
        //提交事务
        [CATransaction commit];

    改变actions 使其有一个过渡效果

      //定义过度类型这里使背影颜色的改变是从左往右的push效果
        CATransition *transiton = [CATransition animation];
        transiton.type = kCATransitionPush;
        transiton.subtype = kCATransitionFromLeft;
        self.colorLayer = layer;
        self.colorLayer.actions = @{@"backgroundColor":transiton};

    自定义action的属性

    当设置自定义layer的radius属性的时候隐式的为当前属性添加动画

     presentationLayer:获取屏幕上真正显示的图层(改变图层属性,视觉上不是直接就显示对应值,所以通过presentationLayer可以获取当前展示的图层的信息)
    

       

    @interface CustomActionLayer : CALayer
    //当改变radius隐式的调用动画效果
    @property(nonatomic,assign)CGFloat radius;
    
    @end
    /**
     必须用dynamic,CALayer为这个属性自动生成存取方法 ,不能用@synthesize
     */
    
    @dynamic radius;
    
    - (instancetype)init{
        if (self = [super init]) {
            [self setNeedsDisplay];
        }
        return self;
    }
    - (void)drawInContext:(CGContextRef)ctx{
        CGContextSetFillColorWithColor(ctx,[UIColor redColor].CGColor);
        CGFloat x = self.bounds.size.width/2 - self.radius/2;
        CGFloat y = self.bounds.size.height/2 - self.radius/2;
       
        CGContextAddEllipseInRect(ctx,CGRectMake(x, y,self.radius, self.radius) );
        CGContextFillPath(ctx);
    }
    + (BOOL)needsDisplayForKey:(NSString *)key{
        if ([key isEqualToString:@"radius"]) {
            return true;
        }
        return [super needsDisplayForKey:key];
        
    }
    
    
    /**
     presentationLayer:获取屏幕上真正显示的图层(改变图层属性,视觉上不是直接就显示对应值,所以通过presentationLayer可以获取当前展示的图层的信息)
     */
    - (id<CAAction>)actionForKey:(NSString *)event{
        if ([self presentationLayer] != nil) {
            if ([event isEqualToString:@"radius"]) {
                CABasicAnimation* basicAni = [CABasicAnimation animationWithKeyPath:@"radius"];
                basicAni.fromValue = [[self presentationLayer] valueForKey:@"radius"];
                return basicAni;
            }
        }
        return [super actionForKey:event];
        
    }

    UIView的layer默认关闭隐式动画

       //uiview关联的layer禁用了隐士动画 覆盖了layer的actionForkey 返回nil
        [UIView beginAnimations:nil context:nil];//开启uivew的隐士动画
        [UIView setAnimationDuration:3.0];//这里设置3.0秒
        self.btn.layer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
        [UIView commitAnimations];

    二.属性动画

    1.CABasicAnimation

    keyPath可取值(收集于网络)

      transform.rotation.x 围绕x轴翻转 参数:角度 angle2Radian(4) 

      transform.rotation.y 围绕y轴翻转 参数:同上 

      transform.rotation.z 围绕z轴翻转 参数:同上 

      transform.rotation 默认围绕z轴 

      transform.scale.x x方向缩放 参数:缩放比例 1.5 

      transform.scale.y y方向缩放 参数:同上 

      transform.scale.z z方向缩放 参数:同上 

      transform.scale 所有方向缩放 参数:同上 

      transform.translation.x x方向移动 参数:x轴上的坐标 100 

      transform.translation.y x方向移动 参数:y轴上的坐标 

      transform.translation.z x方向移动 参数:z轴上的坐标 

      transform.translation 移动 参数:移动到的点 (100,100) 

      opacity 透明度 参数:透明度 0.5 

      backgroundColor 背景颜色 参数:颜色 (id)[[UIColor redColor] CGColor] 

      cornerRadius 圆角 参数:圆角半径 5 

      borderWidth 边框宽度 参数:边框宽度 5 

      bounds 大小 参数:CGRect 

      contents 内容 参数:CGImage 

      contentsRect 可视内容 参数:CGRect 值是0~1之间的小数 

      hidden 是否隐藏 

      position 

      shadowColor 

      shadowOffset 

      shadowOpacity 

      shadowRadius

    各属性值的解释

    Autoreverses 设定这个属性为 YES 时,在它到达目的地之后,动画的返回到开始的值,代替了直接跳转到开始的值,过渡平滑
    Duration 设定开始值到结束值花费的时间。期间会被速度的属性所影响
    RemovedOnCompletion 这个属性默认为 YES,在指定的时间段完成后,动画就自动的从层上移除了。
    FillMode 这个属性一般和 RemovedOnCompletion 配合使用,保持动画状态。其中kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态.此时将RemovedOnCompletion设为NO
    Speed 默认的值为 1.0.如果你改变这个值为 2.0,动画会用 2 倍的速度播放。这样的影响就是使持续时间减半。如果你指定的持续时间为 6 秒,速度为 2.0,动画就会播放 3 秒钟即一半的持续时间。
    RepeatCount 默认的是 0,动画只会播放一次。如果指定一个无限大的重复次数,使用 MAXFLOAT 。这个不应该和 repeatDration 属性一块使用
    RepeatDuration 这个属性指定了动画应该被重复多久。动画会一直重复,直到设定的时间用完。同上它不应该和 repeatCount 一起使用
    FromValue 设置动画的初始值
    ToValue 设置动画的到达值
    TimingFunction 控制动画运行的节奏.    kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉    kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开    kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地    kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
    BeginTime 可以用来设置动画延迟执行时间,若想延迟1s,就设置为CACurrentMediaTime()+1,CACurrentMediaTime()为图层的当前时间
        CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position"];
        basic.delegate = self;
        basic.toValue = [NSValue valueWithCGPoint:point];
        basic.duration = 5.0;
    //    basic.repeatCount = HUGE_VAL  //循环

     //储存终点值用于动画结束后获取

        [basic setValue:[NSValue valueWithCGPoint:point] forKey:@"KBasicPostionKey"];
        [layer addAnimation:basic forKey:@"KBasicPositon"];

      basic.removedOnCompletion = false;

    //位移动画结束后回到结束的位置,如果不这么做 视图回到起始点  
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
        NSLog(@"animationDidStop---");
        [CATransaction begin];//开启事务
        [CATransaction setDisableActions:YES];//关闭隐式动画
        CGPoint point = [[anim valueForKey:@"KBasicPostionKey"] CGPointValue];
        layer.position = point;
        [CATransaction commit];
    }

    暂停动画

        CFTimeInterval time = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
        layer.timeOffset = time;
        
     //speed = 0
        layer.speed = 0;

    恢复动画

         CFTimeInterval beigintime = CACurrentMediaTime() - layer.timeOffset;
         layer.timeOffset = 0;
         layer.beginTime = beigintime;
         layer.speed = 1
    

     关于动画时间的解释:

      

    t = (tp - beginTime) * speed + offset

     t为层上的时间,tp为父图层上的时间

     与图层的层级类似,时间也有层级,修改图层上的时间,会影响该图层和子图层,不影响父图层

     CoreAnimation有一个全局时间的概念,也就是所谓的马赫时间,它在设备上所有进程都是全局的

     图层上的默认时间就是马赫时间,即为CACurrentMediaTime()

     动画停止时,层上时间为pauseTime

     恢复动画时,设置了layer.speed = 1, layer.offset = 0

     t = pauseTime = (tp - beginTime) * speed + offset

     pauseTime = (CACurrentMediaTime() -  beginTime) * 1 + 0

     beginTime = CACurrentMediaTime() - pauseTime

    2. CAKeyframeAnimation

    基本动画只有两个值fromValue和toValue 而关键帧动画可以有多个值

     CAKeyframeAnimation *ani= [CAKeyframeAnimation animationWithKeyPath:@"position"];
        NSValue *key1 = [NSValue valueWithCGPoint:layer.position];
    //不同于基本动画关键帧动画需要设置初始位置
        NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(120, 150)];
        NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(130, 300)];
        NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(110, 600)];
        ani.values = @[key1,key2,key3,key4];
        CAMediaTimingFunction *fn = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
        //每一帧都运用动画缓冲效果
        ani.timingFunctions = @[fn,fn,fn,fn];
        //自定义的缓冲,是个三次贝塞尔曲线,代表变化速率
    //    ani.timingFunction = [CAMediaTimingFunction functionWithControlPoints:1 :0 :0.75 :1];
        //整体缓冲
    //    ani.timingFunction = fn;
        
        ani.duration = 8;
     //    ani.beginTime = CACurrentMediaTime() +3;//延迟3秒
        [layer addAnimation:ani forKey:@"KCAFramPositon"];

    自定义缓冲器:

    定义了两个控制点(可以理解为一条直线被两个点互相吸引导致的变化) 切线代表变化速率

    [CAMediaTimingFunction functionWithControlPoints:1 :0 :0.75 :1];

    关键帧动画还可以指定运动路径

    rotationMode:当沿着路路径变化时自动调整图层方向
     
      CAKeyframeAnimation *ani= [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        CGMutablePathRef path = CGPathCreateMutable();
     
        CGPathMoveToPoint(path, NULL, layer.position.x, layer.position.y);
        CGPathAddCurveToPoint(path, NULL, 150, 160, -30, 80, 60, 400);
        //动画路径
        ani.path = path;
        //沿着路径切线方向
        ani.rotationMode = kCAAnimationRotateAuto;
        CGPathRelease(path);//释放路径对象
        ani.duration = 4;
        ani.beginTime = CACurrentMediaTime() +3;//延迟3秒
        [layer addAnimation:ani forKey:@"KCAFramPositon"];

    动画组

    CAAnimationGroup:

        CAAnimationGroup *group = [CAAnimationGroup animation];
        group.animations = @[ani1,ani2];
    

     转场动画

        CATransition *transtion = [[CATransition alloc] init];
        transtion.type = @"cube";
        transtion.subtype = kCATransitionFromRight;
        transtion.duration = 1;
        _transView.backgroundColor = bkcolors[currentIndex];
        [_transView.layer addAnimation:transtion forKey:nil];

    type的值:

  • 相关阅读:
    Android PopupWindow显示位置和显示大小
    线性回归与梯度下降
    nginx启动过程分析
    项目管理学习笔记之三.绩效分析
    会计总论读书笔记
    电子书阅读及工具
    mybatis-mysql小优化
    List去重
    JAVA8之lambda表达式详解,及stream中的lambda使用
    linux部署mongodb及基本操作
  • 原文地址:https://www.cnblogs.com/cnman/p/10703519.html
Copyright © 2020-2023  润新知