目录
1. Core Animation 核心动画简介
2. CABasicAnimation
3. CAKeyframeAnimation
4. CAAnimaitonGroup
5. CATransition
6. CAMediaTiming
7. 参考链接
<h1 id="1">1. Core Animation 核心动画简介</h1>
Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。
Core Animation 是跨平台的,可以用在Mac OS X 和iOS 平台。
Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程。不阻塞主线程,可以理解为在执行动画的时候还能点击(按钮)。
要注意的是,Core Animation 是直接作用在 CALayer 上的,并非UIView,iOS 的 UIView 背后都有一个对应的 CALayer。对 UIView 的修改实际上都是对背后 CALayer 的修改。
即 Core Animation 不改变 UIView 的 Frame 属性,也就是说并不改变 UIView 的实际位置。
为了更好的理解Core Animation,首先了解一下UIView与CALayer的关系:
一个 Layer 的 frame 是由它的 anchorPoint, position, bounds, 和 transform 共同决定的,而一个 UIView 的 frame 只是简单的返回 CALayer 的 frame,同样 View 的 center和 bounds 也是返回 CALayer 的一些属性。当 CALayer 在背后支持一个 UIView 的时候,UIView 就是它的 delegate。即,UIView 是 CALayer 的CALayerDelegate。
总结UIView和CALayer的区别与联系:
- 1. 首先UIView可以响应事件,Layer不可以.
- 2. UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制。
- **3.在做 iOS 动画的时候,修改非 RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。 **
坐标 信息是 UIView 的一个属性(实际是对应到 CALayer 的属性),在动画实现里,我们只需要指定起始和结束的两个关键值就够了,中间的过渡值都有系统自动生成。这里出现了两种值,一个是我们设定的,一个是系统生成的,所以要先在这里插入一个 模型层 和 展现层 的概念了。
CALayer 的同一个属性值,会分别保存在模型层 modelLayer ,和展现层 presentationLayer 中。当我们修改属性值时,是修改的模型层的数值,动画时系统根据模型层的变化,生成的过渡值,是保存在展现层中的。
在CALayer 的对象里能直接访问到这两层的信息。而CALayer 的底层实现实际不止这两层,但我们现在讨论动画的时候,可以只关心这两层。
在整个动画过程中,呈现出来的过程是这样的:
- 动画前,显示模型层的当前值;
- 动画开始,切换显示展现层的值;
- 动画过程中,展现层的值根据时间变化,我们看到的实际是展现层的值在变化;
- 动画结束,切换回显示模型层的值,此时模型层的值应被修改为动画结束时的值。
由于在动画过程中,修改的只是展现层的值,模型层的值并没有改变,所以Core Animation 并不修改 UIView 的实际位置。(如果要修改UIView 的实际位置,则要手动修改 UIView 的 Frame)
搞清楚UIView和CALayer的关系后,我们开始正式介绍Core Animation。
CAAnimation ( Core Animation ) 是所有动画类的父类,不能直接使用,应该使用它的子类。
CAAnimation 包括三个子类:CAAnimationGroup、CAPropertyAnimation、CATransition。其中,CAPropertyAnimation 也不能直接使用,想要创建动画对象,应该使用它的两个子类:CABasicAnimation 和 CAKeyframeAnimation。
- CABasicAnimation,可设定起始结束两个关键帧的信息。
任何动画要表现出运动或者变化,至少需要两个不同的关键状态,而中间的状态的变化可以通过插值计算完成,从而形成补间动画,表示关键状态的帧叫做关键帧.
- CAKeyframeAnimation,除首尾外,还可添加多个中间关键帧(关键点)。
- CAAnimationGroup,可组合多个动画,因为上面两种动画一次只能设置一个属性值。
- CATransition,图层过渡动画,默认是淡入。比如修改一个 CALayer的背景色时,是从初始色慢慢淡入过渡到结束色。可修改为新颜色把旧颜色顶出去等效果。还可使用 CIFilter 滤镜做过渡效果,一些开源 UIViewController 的过渡动画使用了这种方式。
CAAnimation注意要点:
- 1. 能用的动画类只有4个子类:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup
- 2. CAMediaTiming是一个协议(protocol)
-
3. 属性解析:
CAMediaTiming媒体时间类协议:
1.beginTime 动画开始的时间 默认为0
2.duration 动画的持续时间 默认为0 持续时间 受速度的影响 实际动画完成时间 = 持续时间/速度
3.speed 动画的播放速度 默认为1 速度设置为0 可以暂停动画
如果speed 2 duration 60 那么动画真正播放完成的时间 30秒
4.timeOffset 动画播放时间的偏移量
5.repeatCount 动画的循环次数 默认是0 只播放一次
6.repeatDuration 动画循环的持续时间
repeatCount/repeatDuration 只能设置其中的一个属性
7.autoreverses 是否以动画的形式返回 返回到播放之前的状态
8.fillMode 设置当前对象在非活动时间段的状态
要想fillMode有效 需设置removedOnCompletion = NO
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 立即进入动画的初始状态并等待动画开始
kCAFillModeBoth 动画加入后开始之前 layer处于动画初始状态 动画结束后layer保持动画最后的状态
kCAFillModeRemoved 默认值 动画结束后 layer会恢复到之前的状态
CAAnimation动画属性方法介绍:
1.初始化的方法 animation
2.timingFunction 速度控制类 控制动画运行的节奏
timingFunction的初始化方法: functionWithName:
kCAMediaTimingFunctionLinear 线性,匀速
kCAMediaTimingFunctionEaseIn 慢进后快
kCAMediaTimingFunctionEaseOut 快进后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢进后快再慢出
kCAMediaTimingFunctionDefault 实际效果是动画中间比较快
3.delegate 代理
4.removedOnCompletion 完成动画的时候 是否移除动画效果 默认为YES
5.代理方法
- (void)animationDidStart:(CAAnimation *)anim
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
下图展示了前面四种 Timing Function 的曲线图,横坐标表示时间,纵坐标表示变化量,斜率代表速度。
kCAMediaTimingFunctionLinear 选项创建了一个线性的计时函数,同样也是 CAAnimation 的 timingFunction 属性为空时候的默认函数。
线性步调对于那些立即加速并且保持匀速到达终点的场景会有意义(例如射出枪膛的子弹),但是对大多数的动画来说确实很少用到。
kCAMediaTimingFunctionEaseIn 常量创建了一个慢慢加速然后突然停止的方法。
对于自由落体的例子来说很适合,或者比如对准一个目标的导弹的发射。
kCAMediaTimingFunctionEaseOut 则恰恰相反,它以一个全速开始,然后慢慢减速停止。
它有一个削弱的效果,应用的场景比如一扇门慢慢地关上,而不是砰地一声。
kCAMediaTimingFunctionEaseInEaseOut 创建了一个慢慢加速然后再慢慢减速的过程。这是现实世界大多数物体移动的方式,也是大多数动画来说最好的选择。
如果只可以用一种缓冲函数的话,那就必须是它了。那么你会疑惑为什么这不是默认的选择,实际上当使用UIView的动画方法时,他的确是默认的,但当创建CAAnimation的时候,就需要手动设置它了。
kCAMediaTimingFunctionDefault,它和kCAMediaTimingFunctionEaseInEaseOut 很类似,但是加速和减速的过程都稍微有些慢。
它和 kCAMediaTimingFunctionEaseInEaseOut 的区别很难察觉,可能是苹果觉得它对于隐式动画来说更适合(然后对UIKit就改变了想法,而是使用 kCAMediaTimingFunctionEaseInEaseOut 作为默认效果),
虽然它的名字说是默认的,但还是要记住当创建显式动画的 CAAnimation, 它并不是默认选项(显示动画使用kCAMediaTimingFunctionLinear作为默认效果)。
- 4. Core Animation 不改变 UIView 的 Frame 属性,也就是说并不改变 UIView 的实际位置。(再次强调)
<h1 id = "2">2. CABasicAnimation</h1>
CABasicAnimation 是用于两个关键帧(两种状态)之间的动画。通过设置起始和结束两个关键帧信息,系统自动生成过渡动画。(可以直接设置结束关键帧,则以UIView当前位置为默认起始关键帧**)
属性说明:
- **keyPath **动画类型:
a. 平移动画: position/transform.translation.x
b. 旋转动画 : transform.rotation/transform.rotation.x /transform.rotation/rotation.y
c. 缩放动 画:bounds/transform.scale/transform.scale.x/transform.scale.y
- fromValue 动画开始位置
- **toValue **动画结束位置
- **byValue **动画增加值
- **removedOnCompletion **动画完成后不要删除
- **fillMode **保持最新状态
<h1 id = "3">3. CAKeyframeAnimation</h1>
**CAKeyframeAnimation **是 CABasicAnimation 的升级版,区别在于可以用于多个关键帧(多个状态,多个关键点)。
属性说明:
- **keyPath **动画类型:
a. 平移动画: position/transform.translation.x
b. 旋转动画 : transform.rotation/transform.rotation.x /transform.rotation/rotation.y
c. 缩放动 画:bounds/transform.scale/transform.scale.x/transform.scale.y
- **fromValue **动画开始位置
- **toValue **动画结束位置
- **byValue **动画增加值
- **removedOnCompletion **动画完成后不要删除
- **fillMode **保持最新状态
与 CABasicIAnimation 相比 CAKeyframeAnimation 增加几个属性:
- path:运动的曲线。
path 是一个 **CGPathRef **的值,且 **path **只能对 **CALayer **的 **anchorPoint **和 position 属性起作用,且设置了 path 之 后 **values **就不再起效了
- values: 是一个NSArray对象。里面的元素称为『关键帧』(Keyframe)。动画对象会在指定的时间(duration)内,依次移动到values数组中的每一个关键帧。(values 和 path 是互斥的: 如果设置了 path,values 是被忽略的)
- keyTimes: 为对应的关键帧指定的时间点,该属性是一个数组(数组内容为的 NSNumber 对象),keyTimes中的每一个时间值都对应values中的每一帧,可以为每个关键帧(子路径AB,BC,CD,DE)指定对应的时间点。例如,你可以传入@[@(0.0), @(0.1), @(0.6), @(0.7), 1.0],其中首尾必须分别是0和1。因此,t(AB) = 0.1 - 0, t(BC) = 0.6 - 0.1, t(CD) = 0.7 - 0.6, t(DE) = 1 - 0.7。当keyTimes没有设置的时候,各个关键帧的时间是平分。
- ** timeFunctions:存储timeFunciton类型的数组,用于控制每段动画的运动节奏。(需要注意的是:若keyTimes未设置(各帧时间平分),timesFunctions选择匀速,此时意味着每一段动画都是匀速,而非意味着每一段动画的速度都是相同的。因为速度还取决与距离:时间相同、动画确定是匀速运动,但是距离不同,所以是匀速但速度不同!)
-
calculationMode :主要针对的是每一帧的内容为一个坐标点的情况,也就是对anchorPoint 和 **position **进行的动画。当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算。
calculationMode目前提供如下五种模式:
kCAAnimationLinear calculationMode的默认值,表示当关键帧为坐标点的时候,关键帧之间直接直线相连进行插值计算;
**kCAAnimationDiscrete **表示离散,就是不进行插值计算,所有关键帧直接逐个进行显示;
kCAAnimationPaced 使得动画均匀进行,而不是按keyTimes 设置的或者按关键帧平分时间,此时keyTimes 和timingFunctions 无效;
kCAAnimationCubic 对关键帧为坐标点的关键帧进行圆滑曲线相连后插值计算,对于曲线的形状还可以通过tensionValues, continuityValues,biasValues 来进行自定义调整,这里的数学原理是Kochanek–Bartels spline,这里的主要目的是使得运行的轨迹变得圆滑;
<h1 id = "4">4. CAAnimaitonGroup </h1>
**CAAnimaitonGroup 可以组合多个动画,因为上面两种动画一次只能设置一个属性值。使用CAAnimaitonGroup **,一个CALayer设定了很多动画,他们都会同时按顺序执行。
属性说明:
animations:是一个NSArray对象,用于保存CAKeyframeAnimation和CABasicAnimation对象。实现多种动画效果同时进行。
<h1 id = "5">5. CATransition </h1>
CATransition ** 实际上是苹果帮开发者封装好的一些动画,专门用于做转场动画。(能够为层和视图控制器提供移出屏幕和移入屏幕的动画效果)。UINavigationController就是通过CATransition**实现了将控制器的视图推入屏幕的动画效果。
属性说明:
type:动画过渡效果类型
subtype:动画过渡方向
startProgress:动画起点(在整体动画的百分比,必须小于等于结束点)
endProgress:动画终点(在整体动画的百分比,必须大于等于开始点)
**type **(转场动画的类型)的参数:
|动画类型 |说明 |对应常量 |是否支持方向设置 |
| :-------: | :--: | :--------: | :----------------: |
|公开API:|
| fade | 淡出效果 | kCATransitionFade | 是 |
| movein | 新视图移动到旧视图上 | kCATransitionMoveIn | 是 |
| push | 新视图推出旧视图 | kCATransitionPush | 是 |
| reveal | 移开旧视图显示新视图 | kCATransitionReveal | 是 |
|私有API: |
|私有API只能通过字符串访问,如@"cube"|
| cube | 立方体翻转效果 |无 | 是 |
| oglFlip | 翻转效果 |无 | 是 |
| suckEffect | 收缩效果 |无 | 否 |
| rippleEffect | 水滴波纹效果|无 | 否 |
| pageCurl | 向上翻页效果 |无 | 是 |
| pageUnCurl | 向下翻页效果|无 | 是 |
| cameralIrisHollowOpen | 摄像头打开效果|无 | 否 |
| cameraIrisHollowClose | 摄像头关闭效果|无 | 否 |
subtype(动画过渡方向)的参数
- kCATransitionFromRight:从右侧转场
- kCATransitionFromLeft:从左侧转场
- kCATransitionFromTop:从顶部转场
- kCATransitionFromBottom: 从底部转场
<h1 id = "6">6. CAMediaTiming</h1>
CAMediaTiming是CAAnimation遵守的协议(protocol)定义了一系列的属性。
- beginTime 动画开始的时间 默认为0
- duration 动画的持续时间 默认为0 持续时间 受速度的影响 实际动画完成时间 = 持续时间/速度
- speed 动画的播放速度 默认为1 速度设置为0 可以暂停动画。 如果speed = 2 duration = 60 那么动画真正播放完成的时间 30秒
- timeOffset 动画播放时间的偏移量
- repeatCount 动画的循环次数 默认是0 只播放一次
- repeatDuration 动画循环的持续时间
repeatCount/repeatDuration 只能设置其中的一个属性 - autoreverses 是否以动画的形式返回 返回到播放之前的状态
- fillMode 设置当前对象在非活动时间段的状态,要想fillMode有效 需设置removedOnCompletion = NO
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 立即进入动画的初始状态并等待动画开始
kCAFillModeBoth 动画加入后开始之前 layer处于动画初始状态 动画结束后layer保持动画最后的状态
kCAFillModeRemoved 默认值 动画结束后 layer会恢复到之前的状态
<h5 id = "7">参考链接 </h5>