iOS核心动画之CoreAnimation

CoreAnimation简介

Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。
Core Animation可以用在Mac OS X和iOS平台。
Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

CoreAnimation的结构

iOS核心动画之CoreAnimation_第1张图片
CoreAnimation

CAAnimation和CAPropertyAnimation都是抽象类,不直接使用,我们主要用到的是

  • CAAnimationGroup
  • CABasicAnimation
  • CAKeyframeAnimation
  • CATransition

CoreAnimation的使用步骤

XCode5之前使用CoreAnimation需要先添加QuartzCore.framework和引入对应的框架
具体步骤:

  1. 首先得有CALayer
  2. 初始化一个CAAnimation对象,并设置一些动画相关属性
  3. 通过调用CALayer的addAnimation:forKey:方法,增加CAAnimation对象到CALayer中,这样就能开始执行动画了
  4. 通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画

CAAnimation简介

CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类

属性说明:

  • timingFunction(CAMediaTimingFunction) :速度控制函数,控制动画运行的节奏
    • kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
    • kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
    • kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
    • kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
  • delegate:动画代理
  • removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards

以下属性来自协议CAMediaTiming

  • duration:动画的持续时间
  • repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
  • repeatDuration:重复时间
  • fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后,fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO)
    • kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
    • kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
    • kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
    • kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
  • beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间

CAAnimation动画代理方法

/* Delegate methods for CAAnimation. */
public protocol CAAnimationDelegate : NSObjectProtocol {

    /* Called when the animation begins its active duration. */
    @available(iOS 2.0, *)

    optional public func animationDidStart(_ anim: CAAnimation)
    /* 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. */
    
    @available(iOS 2.0, *)
    optional public func animationDidStop(_ anim: CAAnimation, finished flag: Bool)
}

CAPropertyAnimation

CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:

  • CABasicAnimation
  • CAKeyframeAnimation

属性说明:

  • keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@“position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果

CABasicAnimation

CABasicAnimation基本动画,是CAPropertyAnimation的子类
属性说明:

  • fromValue:keyPath相应属性的初始值
  • toValue:keyPath相应属性的结束值

动画过程说明:

  • 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue
  • keyPath内容是CALayer的可动画Animatable属性
  • 如果fillMode=kCAFillModeForwards同时removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

使用场景

  • 从一个位置到另一个位置的简单动画使用CABasicAnimation
let animation = CABasicAnimation(keyPath: "position.x")
animation.toValue = 300
animation.isRemovedOnCompletion = false
animation.fillMode = "forwards"
animation.repeatCount = Float.infinity
animation.autoreverses = true
animation.duration = 1
redView.layer.add(animation, forKey: "AnimationKey1")

CAKeyFrameAnimation:帧动画

关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:
CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值

属性说明:

  • values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
  • path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
  • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的

使用场景:

  • 删除抖动,从-5度到+5度到-5度,一组值
  • 沿着贝塞尔曲线的路径移动(只有帧动画可以沿着贝塞尔曲线的路径移动)
let animation = CAKeyframeAnimation(keyPath: "transform.rotation")
let angle1 = 5 * Float.pi / 180
let angle2 = -5 * Float.pi / 180
animation.values = [angle1, angle2, angle1]
animation.repeatCount = Float.infinity
animation.duration = 1.3
imageView.layer.add(animation, forKey: "AnimationKey3")

Tips:

  • CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation
  • 只有帧动画才能沿着路径走

CAAnimationGroup:动画组

动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行
默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间

属性说明:

  • animations:用来保存一组动画对象的NSArray

使用场景:

  • 多个动画同时进行,比如往下移动的同时,进行缩放效果
let animation1 = CABasicAnimation(keyPath: "position.y")
animation1.toValue = 400

let animation2 = CABasicAnimation(keyPath: "transform.scale")
animation2.toValue = 0.5

// 创建动画组,用动画组包含多个动画
let group = CAAnimationGroup()
group.animations = [animation1, animation2]
group.fillMode = "forwards"
group.isRemovedOnCompletion = false

redView.layer.add(group, forKey: "group")

CATransition:转场动画

CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点
UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果

动画属性:

  • type:动画过渡类型
  • subtype:动画过渡方向
  • startProgress:动画起点(在整体动画的百分比)
  • endProgress:动画终点(在整体动画的百分比)

使用场景:

  • UINavigationController的push操作就是通过CATransition(转场动画)实现的

转场动画的过渡效果

类型字符串 效果说明 关键字 方向
fade 交叉淡化过渡 YES
push 新视图把旧视图推出去 YES
moveIn 新视图移到旧视图上面 YES
reveal 将旧视图移开,显示下面的新视图 YES
cube 立方体翻滚效果
oglFlip 上下左右翻转效果
suckEffect 收缩效果,如一块布被抽走 No
rippleEffect 水滴效果 No
pageCurl 向上翻页效果
pageUnCurl 向下翻页效果
cameraIrisHollowOpen 相机镜头打开效果 No
cameraIrisHollowClose 相机镜头关闭效果 No
/*
 转场动画
 */
let transition = CATransition()
transition.type = "pageCurl"
transition.subtype = "fromRight"
transition.startProgress = 0.2
transition.endProgress = 0.5
imageView.layer.add(transition, forKey: "AnimationKey5")

Tips

  • 转场代码和转场动画必须在同一个方法中,不考虑顺序(转场动画代码在前还是转场代码在前)

UIView动画和CoreAnimation动画的区别以及不同的适用场景?

不同之处:

  • UIView动画修改了控件的属性真实值,CoreAnimation动画作用在CALayer上,并没有修改控件属性的真实值。也就是CoreAnimation动画看到的都是假象,控件在动画前和动画后没有发生任何改变

适用场景
根据UIView动画和CoreAnimation动画的特点

  • 当我们需要与用户交互时,请使用UIView动画
  • 当需要沿着某条路径移动时,请适用CoreAnimation动画
  • 转场动画请使用CoreAnimation动画

相关代码点我

你可能感兴趣的:(iOS核心动画之CoreAnimation)