核心动画的基本结构
CAAnimation 是个虚类 不能直接使用 继承之下有三个子类 CAAnimationGroup CATransition CAPropertyAnimation 和 一个协议 CAMediaTiming
其中CAPropertyAnimation 又是一个虚类同样不能直接使用 继承之下又有两个子类 也是常用类 CABasicAnimation 和 CAKeyframeAnimation
如果是xcode6 之前 在用 核心动画的时候要先导入<QuartzCore/QuartzCore.h>框架
基本原理
coreAnimation 都是作用在 CALayer 上的。CALayer 只是一个图层不具备事件响应,只负责图层的渲染展示。与view类似 有两个方法
1 添加动画到CALayer addAnimation:forKey: xxx
2 移除动画 removeAnimationForKey: xxx
以自己写的一个登陆动画为实例来具体总结一下:Demo地址 (求点个 star)
1 CABasicAnimation 基本动画
登录按钮环绕实例 按钮变圆 登录实拍颜色变红 都用的是基本动画不在一一列举
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; // key 确定用什么形式动画
rotate.fromValue = 0; //初始值
rotate.toValue = @(M_PI * 2);//最终值 keypath 不一样代表的意义也不一样
rotate.duration = 0.4;//动画持续时间
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];//动画节奏 时间线性函数
rotate.repeatCount = NSNotFound;//重复次数 NSNotFound MAXFLOAT 为无限次
rotate.fillMode = kCAFillModeForwards;//动画结束后的状态
rotate.removedOnCompletion = false;//结束后是否移除
[layer addAnimation:rotate forKey:rotate.keyPath]; //在layer 上添加动画 如果是view 则view.layer
首先是keyPath key 就有很多种形式:
transform.scale = 比例轉換
transform.scale.x = 宽的比例轉換
transform.scale.y = 高的比例轉換
transform.rotation.z = 平面圖的旋轉
opacity = 透明度
margin=边框间隔?
zPosition = 平面图的位置
backgroundColor = 背景色
cornerRadius = layer的角度
borderWidth = 边框宽度
contents = 内容?
bounds = 大小?
contentsRect = 内容矩形
frame = 位置
hidden = 隐藏
mask = 标记
maskToBounds
position = 位置
shadowOffset = 阴影偏移?
shadowColor = 阴影颜色
shadowRadius = 阴影角度
fromValue 和 toValue 一个是初值一个是终值 根据不同的keypath 所填的值有所不同,意义也就不一样。
timingFunction 动画节奏 时间函数:
//kCAMediaTimingFunctionLinear 线性匀速
//kCAMediaTimingFunctionEaseIn 先慢后快
//kCAMediaTimingFunctionEaseOut 先快后慢
//kCAMediaTimingFunctionEaseInEaseOut 中间快两头慢
//kCAMediaTimingFunctionDefault 一般的动画
fillMode动画结束后的状态类型:
// kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
// kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状
// kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
// kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
removedOnCompletion 结束后是否移除
最后记得把 动画添加在相应的layer上
2 CAKeyframeAnimation——关键帧动画
登录按钮 登录失败 左右晃动的实例
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGPoint point = self.layer.position;
keyFrameAnimation.values = @[[NSValue valueWithCGPoint:CGPointMake(point.x, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x - 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x + 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x - 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x + 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x - 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x + 10, point.y)],[NSValue valueWithCGPoint:CGPointMake(point.x, point.y)]];
keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
keyFrameAnimation.duration = 0.5f;
keyFrameAnimation.delegate = self ;
self.layer.position = point;
[self.layer addAnimation:keyFrameAnimation forKey:keyFrameAnimation.keyPath];
关键帧动画 是CABasicAnimation动画的升级版 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,各个关键帧的时间是平分的
所以它可以做一些位置的移动什么的 主要还的看需求。
3 CAAnimationGroup——动画组
动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。
所以当需要在一个图层上集成多个动画的话就可以用到动画组。
属性说明:
animations:用来保存一组动画对象的NSArray
默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间,来达到一定的效果。
CATransition——转场动画
CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。
UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果
动画属性:
type:动画过渡类型
subtype:动画过渡方向
startProgress:动画起点(在整体动画的百分比)
endProgress:动画终点(在整体动画的百分比)
1. 单视图
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
参数说明:
duration:动画的持续时间
view:需要进行转场动画的视图
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
2. 双视图
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion;
参数说明:
duration:动画的持续时间
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
3. 自定义转场(其实还是属于系统写好的)
创建转场动画:[CATransition animation]
设置动画属性值
添加到需要转场动画的图层上 [layer addAnimation:animation forKey:nil]
转场动画的类型(NSString *type)
fade : 交叉淡化过渡
push : 新视图把旧视图推出去
moveIn: 新视图移到旧视图上面
reveal: 将旧视图移开,显示下面的新视图
cube : 立方体翻滚效果
oglFlip : 上下左右翻转效果
suckEffect : 收缩效果,如一块布被抽走
rippleEffect: 水滴效果
pageCurl : 向上翻页效果
pageUnCurl : 向下翻页效果
cameraIrisHollowOpen : 相机镜头打开效果
cameraIrisHollowClos : 相机镜头关闭效果
转场动画的方向(NSString *subtype)
从某个方向开始:fromLeft, fromRight, fromTop ,fromBottom
4 真正的自定义转场
王巍的转场动画讲解 在这里是王魏对iOS7后出现的自定义转场动画做比较详细的讲解,
如果你想要进一步的研究可以进去看看相信可以学到很多。//关于转场的真正操作只需要遵守协议 UIViewControllerAnimatedTransitioning,CAAnimationDelegate
//实现两个方法:
1 - (NSTimeInterval)transitionDuration:(id)transitionContext 在这里设定转场所用时间// 2 - (void)animateTransition:(id)transitionContext 具体的转场操作在这而函数中实现就可以了
CoreAnimation中的CALayer
1. CAReplicatorLayer:复制图层
顾名思义,复制图层就是用来复制的。它会将自己的子图层进行复制,连同子layer上的动画会一起复制。
属性说明:
instanceCount :复制份数。(会把原始的子图层复制多少份,包括原来的一份)
instanceTransform:形变。每一份相对上一份的形变量
instanceDelay :每一份相对上一份的时间延迟。
修改CAReplicatorLayer的颜色通道,可以改变CAReplicatorLayer的显示的样式
@property float instanceRedOffset;
@property float instanceGreenOffset;
@property float instanceBlueOffset;
@property float instanceAlphaOffset;
2. CAShapeLayer:形状图层
根据形状,绘制内容的图层
属性说明:
path:描述形状的路径。默认会把路径封闭,然后填充。
fillColor :填充的颜色
strokeColor:描边的颜色(如果想仅仅只描边的话,就把fillColor设为clearcolor就好)
strokeStart:开始描边的比例【0-1】
strokeEnd:结束描边的比例【0-1】
3. CAGradientLayer:渐变图层
用这个图层,可以做颜色的渐变
属性说明:
colors :保存所有渐变的颜色,里面是CGColorRef,记得用id,让编译器以为数组里面的是OC对象。
locations :保存所有渐变的位置【0-1】
startPoint:开始渐变的点【0-1】
endPoint:结束渐变的点【0-1】
4 CAAnimation代理方法
CAAnimation在分类中定义了代理方法。是给NSObject添加的分类,所以任何对象,成为CAAnimation的代理,都可以。
动画开始的时候调用
- (void)animationDidStart:(CAAnimation *)anim;
动画停止的时候调用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
5 CALayer上动画的暂停和恢复
暂停
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 让CALayer的时间停止走动
layer.speed = 0.0;
// 让CALayer的时间停留在pausedTime这个时刻
layer.timeOffset = pausedTime;
}
恢复
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = layer.timeOffset;
// 1. 让CALayer的时间继续行走
layer.speed = 1.0;
// 2. 取消上次记录的停留时刻
layer.timeOffset = 0.0;
// 3. 取消上次设置的时间
layer.beginTime = 0.0;
// 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
// 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
layer.beginTime = timeSincePause;
}
注意:
核心动画给我们展示的只是一个假象,layer的的frame、bounds、position并不会在动画完毕之后发生改变。
UIView封装的动画,会使会真实修改view的一些属性。
UIView 常用的分装动画:
1 基本动画 一般用于简单的只有一个动效的动画
[UIView animateWithDuration:(NSTimeInterval) animations:^{
}]
2 升级版的可以多层嵌套 完成稍微复杂点的动画
[UIView animateWithDuration:(NSTimeInterval) animations:^{
在这里写要操作的动画
} completion:^(BOOL finished) {
这里进行动画结束后的操作
}]
3 带有弹簧动效的动画
[UIView animateWithDuration:(NSTimeInterval) delay:(NSTimeInterval) // 动画延迟时间 usingSpringWithDamping:0< =弹性系数 <=1 initialSpringVelocity: options:(UIViewAnimationOptions) animations:^{
} completion:^(BOOL finished) {
}]
本人自己平时积累研究动画的时候写了一个小的动画库,已经封装好需要的接口。可以直接脱出需要的动画用。(特殊需要自己修改)藤王俊采 动画Demo