zoukankan      html  css  js  c++  java
  • iOS动画原理

    1. iOS动画原理

    • 本质:动画对象(这里是UIView)的状态,基于时间变化的反应
    • 分类:可以分为显式动画(关键帧动画和逐帧动画)和隐式动画
    • 关键帧和逐帧总结:关键帧动画的实现方式,只需要修改某个属性值就可以了,简单方便,但涉及的深层次内容较多,需要更多的理解和练习。采用逐帧动画的实现方式,实现原理简单,但绘制动画的过程要复杂。如果动画过程处理的事情较多,也会带来较大的开销,就有可能造成动画帧数的下降,出现卡顿的现象,因此需要较多的测试和调试。

    1.1 显式动画(逐帧动画和关键帧动画)

    显式动画本质是我们显式地给CALayer添加一个动画

    • 逐帧动画

      • 用户需要周期性的调用绘制方法,绘制每帧的动画对象,系统操作方法简单,但用户操作的工作量就会大一些
      • 周期性这边指的是定时器CADisplayLink,其基于屏幕刷效率的,即屏幕每次刷新时就会触发调用(iPhone为60FPS)。
      • 绘制指的是对UIView背后对应的主CALayer进行的修改,这边的修改包括- drawRect:方法和UIView的属性渐变(改变颜色尺寸等)。
      • 注意1:因为有些时候绘制过程相对复杂,所以一般采用每隔一帧进行绘制,相当于30FPS的刷新率。另外著名的pop动画框架,就是用CADisplayLink进行的逐帧动画。
      • 注意2:如果在逐帧绘制的方法中修改了一个自建的CALayer,这个CALayer不是对应某个UIView的,需注意系统的隐式动画的影响,后面会提到这点。
    • 关键帧动画

      • 主要是使用两个关键帧---起始帧和结束帧,再配合别的关键信息(如动画时间和运动类型等)
      • 每个CALayer都有一个属性来表示成坐标,我们可以修改模型层modelLayer来改变展现层presentationLayer来形成动画效果。
      • 整个动画过程,通过坐标层次来看如下所示:
        • 动画前,显示模型层的当前值;
        • 动画开始,切换显示展现层的值;
        • 动画过程中,展现层的值根据时间变化,我们看到的实际是展现层的值在变化;
        • 动画结束,切换回显示模型层的值,此时模型层的值应被修改为动画结束时的值。
      • 代码注释如下:
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        view.backgroundColor = [UIColor redColor];
        [self.view addSubview:view];
        
        // CABasicAnimation指定一个keyPath,详见官方API
        // 常见keyPath:transform.scale/transform.translation.x/position.x(非3D平移)
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
        // 开始帧
        animationWithKeyPath.fromValue = @(100);
        // 结束帧
        animationWithKeyPath.fromValue = @(200);
        // 动画时间
        animation.duration = 2.0;
        // 永久重复动画
        animation.repeatCount = HUGE;
        // 代理方法:
        // - (void)animationDidStart:(CAAnimation *)anim;
        // - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
        animation.delegate = self;
        // fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
        animation.fillMode = kCAFillModeForwards;
        // removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
        animation.removedOnCompletion = NO;
        // autoreverses:动画结束时是否执行逆动画
        animation.autoreverses = NO;
        // timingFunction:动画类型,设定动画的速度变化
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        // 给CALayer添加一个动画,该动画为CAAnimation类型,其子类有CABasicAnimation/CAKeyframeAnimation/CAAnimationGroup/CATransition(图层过度动画,有filter属性)
        [view.layer addAnimation:animation forKey:nil];
        

    1.2 隐式动画

    当前UIView的主CALayer称为根层,自动另外创建的CALayer为非根层,对非根层的部分可动画属性修改时,就是隐式动画。

    • 直接对UIView或其CALayer设置一个可动画的属性值时,会出发系统的隐式动画,可动画的属性值,可以在UIView或其CALayer的文档中找到,属性标有Animatable
    • 注意:
      • 因为主CALayer,系统默认关闭了隐式动画,所以当我们直接修改这些可动画属性值时,变化时直接生效的,没有动画效果。
      • 如果修改的是一个自建的单独CALayer时,帧与帧之间的变化还是会触发系统的默认隐式动画,这个时候就需要我们来手动关闭隐式动画
      • 隐式动画所做的事情和显示动画是一样的,我们设置的属性值都是模型层的数值,而系统会自动添加属性对应的CAAnimation动画到CALayer上。
      • UIView有一系列的animateWithDuration动画方法,在这些方法中UIView会恢复隐式动画,所以在动画的block中修改属性时,又会触发隐式动画。
  • 相关阅读:
    poj3278 Catch That Cow
    poj2251 Dungeon Master
    poj1321 棋盘问题
    poj3083 Children of the Candy Cor
    jvm基础知识—垃圾回收机制
    jvm基础知识1
    java面试基础必备
    java soket通信总结 bio nio aio的区别和总结
    java scoket aIO 通信
    java scoket Blocking 阻塞IO socket通信四
  • 原文地址:https://www.cnblogs.com/LongLJ/p/6113347.html
Copyright © 2011-2022 走看看