快速上手核心动画
1、什么是核心动画
Core Animation 是一套包含图形绘制、投影、动画的 Objective-C 类集合,该框架包含在 QuartzCore.framework 中,它因为被用于处理更为强大的平滑的转场效果而引入 OS X Leopard 和 iOS 而出名。Core Animation 和其它框架的位置关系如下图所示:
上图中的 OpenGL ES 是个 C 语言写的非常底层的图形处理框架,是个移动设备上绘制 2D 和 3D 计算机图形的标准开源库,广泛地被用在游戏的图形绘制上,负责直接驱动 GPU,效率非常高,缺点是使用起来异常复杂。
Core Animation 是对 OpenGL ES 的 Objective-C 封装,具有与 OpenGL ES 几乎等价的高性能,却隐藏了 OpenGL ES 的复杂性。
2、核心动画类的层次结构
核心动画中可以直接使用的类有:
CABasicAnimation
CAKeyframeAnimation
CAAnimationGroup
CATransition
CASpringAnimation
常用属性有:
- duration : 动画的持续时间
- beginTime : 动画的开始时间
- repeatCount : 动画的重复次数
- autoreverses : 执行的动画按照原动画返回执行
- timingFunction : 控制动画的显示节奏系统提供五种值选择,分别是:
kCAMediaTimingFunctionLinear 线性动画
kCAMediaTimingFunctionEaseIn 先慢后快
kCAMediaTimingFunctionEaseOut 先快后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
kCAMediaTimingFunctionDefault 默认,也属于中间比较快
- fillMode:决定当前对象在非 active 时间段的行为. 比如动画开始之前, 动画结束之后
- beginTime:可以用来设置动画延迟执行时间,若想延迟 2s,就设置为 CACurrentMediaTime()+2,CACurrentMediaTime() 为图层的当前时间
- delegate : 动画代理。能够检测动画的执行和结束。
- @interface NSObject (CAAnimationDelegate)
- @optional
- - (void)animationDidStart:(CAAnimation *)anim;
- - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
- @end
- path:关键帧动画中的执行路径
- type : 过渡动画的动画类型,系统提供了四种过渡动画。
kCATransitionFade 渐变效果
kCATransitionMoveIn 进入覆盖效果
kCATransitionPush 推出效果
kCATransitionReveal 揭露离开效果
- subtype : 过渡动画的动画方向
kCATransitionFromRight 从右侧进入
kCATransitionFromLeft 从左侧进入
kCATransitionFromTop 从顶部进入
kCATransitionFromBottom 从底部进入
3、常见类介绍
CABasicAnimation
CABasicAnimation 可以设定 keyPath 的起点,终点的值,动画会沿着设定点进行移动,CABasicAnimation 可以看成是只有两个关键点的特殊的 CAKeyFrameAnimation。
重要属性:
- fromValue : keyPath 对应的初始值
- toValue : keyPath 对应的结束值
基础动画主要提供了对于 CALayer 对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。
注意点:
如果 fillMode = kCAFillModeForwards 和 removedOnComletion = NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
- CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
- positionAnima.duration = 0.8;
- positionAnima.fromValue = @(_iconView.center.y);
- positionAnima.toValue = @(_iconView.center.y-30);
- positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
- positionAnima.repeatCount = HUGE_VALF;
- positionAnima.repeatDuration = 2;
- positionAnima.removedOnCompletion = NO;
- positionAnima.fillMode = kCAFillModeBackwards;
- positionAnima.delegate = self;
- [positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];
- [_iconView.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];
CAKeyframeAnimation
可以设定 keyPath 起点、中间关键点(不止一个)、终点的值,每一帧所对应的时间,动画会沿着设定点进行移动。
重要属性:
- values : 键帧数组对象,里面每一个元素即为一个关键帧,动画会在对应的时间段内,依次执行数组中每一个关键帧的动画。
- path : 动画路径对象,可以设置一个 CGPathRef\CGMutablePathRef, 让层跟着路径移动。path 只对 CALayer 的 anchorPoint 和 position 起作用。如果你设置了 path,那么 values 将被忽略。
- keyTimes : 可以为对应的关键帧指定对应的时间点, 其取值范围为 0 到 1.0,keyTimes 中的每一个时间值都对应 values 中的每一帧. 如果没有设置该属性,则每一帧的时间平分。
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
animation.duration = 0.25;
animation.repeatCount = 10;
animation.values = @[@0.0,@(-M_PI_4/4),@0.0,@(M_PI_4/4),@0.0];
animation.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1.0];
[_iconView.layer addAnimation:animation forKey:@"AnimationKey"];
CAAnimationGroup
CAAnimation 的子类,可以保存一组动画对象,将 CAAnimationGroup 对象加入层后,组中所有动画对象可以同时并发运行。
重要属性:
- animations : 用来保存一组动画对象的 NSArray
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(self.iconView.center.y);
positionAnima.toValue = @(self.iconView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[positionAnima,transformAnima];
[self.iconView.layer addAnimation:animaGroup forKey:@"Animation"];
CATransition
转场动画,比 UIVIew 转场动画具有更多的动画效果,比如 Nav 的默认 Push 视图的效果就是通过 CATransition 的 kCATransitionPush 类型来实现。
重要属性:
- type :动画过渡类型
Apple 官方的 SDK 其实只提供了四种过渡效果。
kCATransitionFade 渐变效果
kCATransitionMoveIn 进入覆盖效果
kCATransitionPush 推出效果
kCATransitionReveal 揭露离开效果
还有一些私有 API 的动画类型,效果很炫酷,不过不推荐使用。比如:"cube"、"suckEffect"、"oglFlip"、"rippleEffect"、"pageCurl"、"pageUnCurl"、"cameraIrisHollowOpen"、"cameraIrisHollowClose" 等等。
- subtype :动画过渡方向
kCATransitionFromRight 从右侧进入
kCATransitionFromLeft 从左侧进入
kCATransitionFromTop 从顶部进入
kCATransitionFromBottom 从底部进入
- startProgress :动画起点 (在整体动画的百分比)
- endProgress :动画终点 (在整体动画的百分比)
CATransition * transitionAnima = [CATransition animation];
transitionAnima.type = kCATransitionMoveIn;
transitionAnima.subtype = kCATransitionFromRight;
transitionAnima.duration = 2.5;
_iconView.image = [UIImage imageNamed:@"paopao"];
[_iconView.layer addAnimation:transitionAnima forKey:@"transitionAnima"];
CASpringAnimation
CASpringAnimation 是 iOS9 新加入动画类型,是 CABasicAnimation 的子类,用于实现弹簧动画。
CASpringAnimation 和 UIView 的 SpringAnimation 对比:
1.CASpringAnimation 可以设置更多影响弹簧动画效果的属性,可以实现更复杂的弹簧动画效果,且可以和其他动画组合。
2.UIView 的 SpringAnimation 实际上就是通过 CASpringAnimation 来实现。
重要属性:
- mass:质量(影响弹簧的惯性,质量越大,弹簧惯性越大,运动的幅度越大)
- stiffness:弹性系数(弹性系数越大,弹簧的运动越快)
- damping:阻尼系数(阻尼系数越大,弹簧的停止越快)
- initialVelocity:初始速率(弹簧动画的初始速度大小,弹簧运动的初始方向与初始速率的正负一致,若初始速率为 0,表示忽略该属性)
- settlingDuration:结算时间(根据动画参数估算弹簧开始运动到停止的时间,动画设置的时间最好根据此时间来设置)
CASpringAnimation * springAnima = [CASpringAnimation animationWithKeyPath:@"bounds"];
springAnima.mass = 10.0; // 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
springAnima.stiffness = 5000; // 刚度系数 (劲度系数 / 弹性系数),刚度系数越大,形变产生的力就越大,运动越快
springAnima.damping = 100.0;// 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
springAnima.initialVelocity = 3.0;// 初始速率,动画视图的初始速度大小; 速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
springAnima.duration = springAnima.settlingDuration;
springAnima.toValue = [NSValue valueWithCGRect:CGRectMake(100, 200, 200, 200)];
springAnima.removedOnCompletion = NO;
springAnima.fillMode = kCAFillModeForwards;
springAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.iconView.layer addAnimation:ani forKey:@"boundsAni"];
CATransaction
CoreAnimation 中还有一个非常重要的类:CATransaction 事务类,这个可以同时设置多个 layer 层的动画效果。可以通过隐式和显式两种方式来进行动画操作。
事务实际上是 Core Animation 用来包含一系列属性动画集合的机制,任何用指定事务去改变可以做动画的图层属性都不会立刻发生变化,而是当事务一旦提交的时候开始用一个动画过渡到新值。
事务是通过 CATransaction 类来做管理,这个类的设计有些奇怪,不像你从它的命名预期的那样去管理一个简单的事务,而是管理了一叠你不能访问的事务。CATransaction 没有属性或者实例方法,并且也不能用 + alloc 和 - init 方法创建它。但是可以用 + begin 和 + commit 分别来入栈或者出栈。
任何可以做动画的图层属性都会被添加到栈顶的事务,你可以通过 + setAnimationDuration: 方法设置当前事务的动画时间,或者通过 + animationDuration 方法来获取值(默认 0.25 秒)。
Core Animation 在每个 run loop 周期中自动开始一次新的事务(run loop 是 iOS 负责收集用户输入,处理定时器或者网络事件并且重新绘制屏幕的东西),即使你不显式的用 [CATransaction begin] 开始一次事务,任何在一次 run loop 循环中属性的改变都会被集中起来,然后做一次 0.25 秒的动画。
事务的作用:保证一个或多个 layer 的一个或多个属性变化同时进行
事务分为隐式和显式:
1. 隐式:没有明显调用事务的方法,由系统自动生成事务。比如直接设置一个 layer 的 position 属性,则会在当前线程自动生成一个事务,并在下一个 runLoop 中自动 commit 事务。
2. 显式:明显调用事务的方法([CATransaction begin] 和 [CATransaction commit])。
对 layer 层的属性操作,都会形成隐式动画,要使用隐式动画,需要关闭 layer 层的 animation 动画属性,使用下面的方法:
- //关闭animation动画效果,开启隐式动画
- + (BOOL)disableActions;
- + (void)setDisableActions:(BOOL)flag;
事务的可设置属性(会覆盖隐式动画的设置):
- animationDuration:动画时间
- animationTimingFunction:动画时间曲线
- disableActions:是否关闭动画
- completionBlock:动画执行完毕的回调
事务支持嵌套使用:当最外层的事务 commit 后动画才会开始。
使用实例:
- [CATransaction begin];
- [CATransaction setAnimationDuration:2.0];
- [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
- self.iconView.layer.bounds = self.showView.layer.bounds;
- [CATransaction commit];
来源: http://www.cnblogs.com/dongliu/p/6541901.html