动画编程 | 青训营笔记

148 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的第16天

UIView 动画

Block 动画

UIView 提供了 Block 动画接口,调用方式简洁,日常开发中也使用 Block 动画,最简洁的 Block 动画包含时间动画

[UIView animateWithDuration:(NSTimeInterval)  //动画持续时间
              animations:^{
              //执行的动画
 }];

带有动画提交回调的 Block 动画

[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
                   delay:(NSTimeInterval) //动画延迟执行的时间
                 options:(UIViewAnimationOptions) //动画的过渡效果
              animations:^{
               //执行的动画
 }                completion:^(BOOL finished) {
               //动画执行提交后的操作
 }];

UIViewAnimationOptions 的枚举值如下,可组合使用:optiona | optionb

// UIViewAnimationOptions 的枚举值:
 UIViewAnimationOptionLayoutSubviews            //进行动画时布局子控件
 UIViewAnimationOptionAllowUserInteraction      //进行动画时允许用户交互
 UIViewAnimationOptionBeginFromCurrentState     //从当前状态开始动画
 UIViewAnimationOptionRepeat                    //无限重复执行动画
 UIViewAnimationOptionAutoreverse               //执行动画回路
 UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
 UIViewAnimationOptionOverrideInheritedCurve    //忽略嵌套动画的曲线设置
 UIViewAnimationOptionAllowAnimatedContent      //转场:进行动画时重绘视图
 UIViewAnimationOptionShowHideTransitionViews   //转场:移除(添加和移除图层的)动画效果
 UIViewAnimationOptionOverrideInheritedOptions  //不继承父动画设置

 UIViewAnimationOptionCurveEaseInOut            //时间曲线,慢进慢出(默认值)
 UIViewAnimationOptionCurveEaseIn               //时间曲线,慢进
 UIViewAnimationOptionCurveEaseOut              //时间曲线,慢出
 UIViewAnimationOptionCurveLinear               //时间曲线,匀速

 UIViewAnimationOptionTransitionNone            //转场,不使用动画
 UIViewAnimationOptionTransitionFlipFromLeft    //转场,从左向右旋转翻页
 UIViewAnimationOptionTransitionFlipFromRight   //转场,从右向左旋转翻页
 UIViewAnimationOptionTransitionCurlUp          //转场,下往上卷曲翻页
 UIViewAnimationOptionTransitionCurlDown        //转场,从上往下卷曲翻页
 UIViewAnimationOptionTransitionCrossDissolve   //转场,交叉消失和出现
 UIViewAnimationOptionTransitionFlipFromTop     //转场,从上向下旋转翻页
 UIViewAnimationOptionTransitionFlipFromBottom  //转场,从下向上旋转翻页

弹簧动画

ios7.0 以后新增了 Spring 动画 (iOS 系统动画大部分采用 Spring Animation,适用所有可被添加动画效果的属性)

self.redView.alpha = 0.0;
[UIView animateWithDuration:(NSTimeInterval)//动画持续时间
                   delay:(NSTimeInterval)//动画延迟执行的时间
  usingSpringWithDamping:(CGFloat)//震动效果,范围0~1,数值越小震动效果越明显
   initialSpringVelocity:(CGFloat)//初始速度,数值越大初始速度越快
                 options:(UIViewAnimationOptions)//动画的过渡效果
              animations:^{
                 //执行的动画
                self.redView.alpha = 1.0;
        self.redView.frame = CGRectMake(200, 350, 140, 140);
 }
                  completion:^(BOOL finished) {
                 //动画执行提交后的操作
 }];

关键帧动画

 // iOS7.0 后新增了关键帧动画,支持属性关键帧,不支持路径关键帧
 [UIView animateKeyframesWithDuration:(NSTimeInterval)//动画持续时间
                            delay:(NSTimeInterval)//动画延迟执行的时间
                          options:(UIViewKeyframeAnimationOptions)//动画的过渡效果
                       animations:^{
                     //执行的关键帧动画
 }
                       completion:^(BOOL finished) {
                     //动画执行提交后的操作
 }];

关键帧选项 UIViewKeyframeAnimationOptions枚举值如下,可组合使用:

UIViewAnimationOptionLayoutSubviews           //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction     //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState    //从当前状态开始动画
UIViewAnimationOptionRepeat                   //无限重复执行动画
UIViewAnimationOptionAutoreverse              //执行动画回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置

UIViewKeyframeAnimationOptionCalculationModeLinear     //运算模式 :连续
UIViewKeyframeAnimationOptionCalculationModeDiscrete   //运算模式 :离散
UIViewKeyframeAnimationOptionCalculationModePaced      //运算模式 :均匀执行
UIViewKeyframeAnimationOptionCalculationModeCubic      //运算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //运算模式 :平滑均匀

增加关键帧方法:

[UIView addKeyframeWithRelativeStartTime:(double)//动画开始的时间(占总时间的比例)
                     relativeDuration:(double) //动画持续时间(占总时间的比例)
                           animations:^{
                         //执行的动画
 }];

转场动画

双视图:从旧视图到新视图的动画效果

[UIView transitionFromView:(nonnull UIView *) toView:(nonnull UIView *) duration:(NSTimeInterval) options:(UIViewAnimationOptions) completion:^(BOOL finished) {
                 //动画执行提交后的操作
 }];

在该动画过程中,fromView 会从父视图中移除,并将 toView 添加到父视图中,注意转场动画的作用对象是父视图(过渡效果体现在父视图上)。调用该方法相当于执行下面两句代码

[fromView.superview addSubview:toView];
[fromView removeFromSuperview];

核心动画

CAAnimation 类继承关系

核心动画类中可以直接使用的类有:

  • CABasicAnimation
  • CAKeyframeAnimation
  • CATransition
  • CAAnimationGroup
  • CASpringAnimation

使用核心动画时需要注意的点:

  • 所有的动画类都遵守 CAMediaTiming
  • CAAnimationCAPropertyAnimation 都是抽象类,不具有动画效果,携带动画类共有的一些属性
  • 动画组由多个动画对象组成
  • 基础动画只有初始态和最终态
  • 关键帧动画保存多个状态或路径点,逐个展示
  • 通过 KeyPath 设置动画属性

核心动画类的常用属性

  • KeyPath:可以指定 KeyPathCALayer 的属性值,并对它修改,注意部分属性是不支持动画的
  • duration:动画的持续时间
  • repeatCount: 动画的重复次数
  • timingFunction:动画曲线(时间节奏控制)
  • fillMode:视图在非 Active 时的行为
  • removedOnCompletion:动画执行完毕后是否从图层上移除,默认为 YES(视图会恢复到动画前的状态),可设置为 NO(图层保持动画执行后的状态,前提是 fillMode 设置为 kCAFillModeForwards
  • beginTime:动画延迟执行时间(通过 CACurrentMediaTime() + your time 设置)
  • delegate:代理

CABasicAnimation——基本动画

通过属性控制动画的参数,只要有初始状态fromValue和结束状态toValue就可实现动画效果,只能针对属性进行单一值变化的动画

CABasicAnimation 有三个比较重要的属性:fromValuetoValuebyValue,都是可选的,但不能同时多于两个为非空,最终都是为了确定 animation 变化的起点和终点,中间的值是通过插值方式计算出来的。插值计算的结果由 timingFunction 指定,默认 timingFunctionnil:线性 liner 均匀变化的

关键属性

  • keyPath 表示需要变化的属性的名称
  • fromValue 初始状态值
  • toValue 结束状态值
  • byValue 在当前值的基础上累加的偏移值。

CAKeyframeAnimation——关键帧动画

CAKeyframeAnimation和CABasicAnimation都是CAPropertyAnimation的子类,前者可以控制动画的全过程,后者可理解成只关注起点和终点的CAKeyframeAnimation。通过属性控制动画的参数,但与基础动画不同的是有多个控制状态,并且可以通过path来实现动画。

关键属性

  • values:需要变化到的值,每个值对应一个关键帧

  • path:让图层跟随路径移动,只针对 anchorPoint、postion 生效。(比如 CGPathRefbezierPath

  • keyTimes:对应关键帧的时间点

  • calculateMode:关键帧之间进行差值计算的方式

CAAnimationGroup-动画组

一种组合动画,可以通过动画组来进行所有动画行为的统一控制,组中动画效果可以并发执行

关键属性

  • animations:添加到动画组的其他动画
  • duration:动画组执行的时间间隔

Lottie 动画

一种跨平台复杂动画的实现,支持iOS、android、web、react native等。通过JSON来描述动画过程

  • 很多复杂的动画是我们使用自带动画 API 无法实现的
  • lottie 是一个第三方的开源库,在使用时需要先通过 CocoaPods 接入 lottie 库
  • 创建 lottie 动画只需要调用 lottie api,注入描述动画的 json 文件即可

lottie 动画的创建

一行代码搞定,firelottie 动画 json 文件名,这是最常用的一种创建 lottie 的方式

LOTAnimationView *lottieView = [LOTAnimationView animationNamed:@"fire"];

lottie动画的控制

  • 在 Lottie 的 API 中我们可以看到,只需要简单的 [lottieView play] 即可播放动画
  • 有时候需要在动画播放完毕时,做一些事情,那么可以使用 playWithCompletion
  • 播放过程中,可以调用 pause 或者 stop 方法暂停或者停止

lottie 动画也给我们提供了一些可以设置的属性,包括是否循环,动画执行时间,查看动画进度等等