最近在研究iOS动画,iOS中添加动画的方法:UIView
的简单动画,layer
的隐式动画,还有Core Animation
和pop
等....
简单介绍
-
Core Animation
,译为核心动画,是苹果提供的非常强大的动画处理API
. -
Core Animation
的动画执行过程都是在后台操作的,不会阻塞主线程。 -
Core Animation
是作用于CALayer
上的动画,每一个继承与UIView
的子类都有一个layer属性,可以通过这个layer来为更改相应view的形式,或者做动画。
Core Animation类的继承关系图
CAAnimation
注意2个属性
timingFunction 动画速度
kCAMediaTimingFunctionLinear 线性,匀速
kCAMediaTimingFunctionEaseIn 渐进,逐渐进入,然后加速完成
kCAMediaTimingFunctionEaseOut 渐出,动画全速进入,然后缓慢完成
kCAMediaTimingFunctionEaseInEaseOut 渐进渐出
removedOnCompletion
默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。
如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode
CAMediaTiming
CAMediaTiming
是CAAnimation
遵守的协议
CAMediaTiming
中的属性
beginTime 动画的开始时间(如果超过的duration,那么动画不会开始)
duration 动画的持续时间
speed 动画的速度
repeatCount 重复次数,默认为0,无限重复可以设置为HUGE_VALF或者MAXFLOAT
repeatDuration 动画重复时间,默认为0
fillMode 决定当前对象在非active时间段的行为。(要想fillMode有效,最好设置removedOnCompletion = NO)
fillMode类型:
kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
kCAFillModeBoth 这个其实就是上面两个的合成,动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
3.Core Animation使用的三步骤
1.创建动画.
2.设置相关属性.
3.将动画添加到某个layer.
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;
也可以移除动画
- (void)removeAnimationForKey:(NSString *)key;
CABasicAnimation 基本动画
通过设置fromValue
和toValue
传入指定的keyPath
可以以动画的形式改变控件的一些属性 如平移,缩放,旋转
fromValue 指定属性(keyPath)开始的值
toValue 指定属性结束时的值
byValue 在原有的值上改变
示例代码
//1.创建动画.
CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
//设置相关属性
basicAnimation.keyPath = @"position.x";
basicAnimation.byValue = @(10);
// 不希望回到原来的位置
basicAnimation.fillMode = kCAFillModeBoth;
basicAnimation.removedOnCompletion = NO;
//将动画添加到某个layer.
[self.button.layer addAnimation:basicAnimation forKey:nil];
CAKeyframeAnimation 关键帧动画
与CABasicAnimation
不同的是CAKeyframeAnimation
会使用一个NSArray
保存一组关键帧,而且通过绘图来指定路径。而CABasicAnimation
只能从一个数值(fromValue
)变换成另一个数值(toValue
)
通过数组的形式
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(150, 200)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(150, 400)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, 200)];
keyframeAnimation.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
keyframeAnimation.duration = 3.f;
keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
keyframeAnimation.delegate = self;
[self.customView.layer addAnimation:keyframeAnimation forKey:nil];
通过设置路径的形式
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
keyframeAnimation.path = path.CGPath;
keyframeAnimation.duration = 2.0f;
[self.customView.layer addAnimation:keyframeAnimation forKey:nil];
CAAnimationGroup 组动画
CAAnimationGroup
可以保存一组动画对象(比如可以把前面的2中动画结合起来),将CAAnimationGroup
对象加入层后,组中所有动画对象可以同时并发运行。
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(150, 200)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(150, 400)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width, 200)];
keyframeAnimation.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
keyframeAnimation.duration = 4.f;
keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
// 缩放
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anima.fromValue = [NSNumber numberWithFloat:0.8f];
anima.toValue = [NSNumber numberWithFloat:2.0f];
// 旋转动画
CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anima2.toValue = [NSNumber numberWithFloat:M_PI*4];
//组动画
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = [NSArray arrayWithObjects:keyframeAnimation,anima,anima2, nil];
groupAnimation.duration = 4.f;
[self.customView.layer addAnimation:groupAnimation forKey:nil];
CATransition 过渡动画
- 能够为层提供移出屏幕和移入屏幕的动画效果
基本属性
type:动画过渡类型
subtype:动画过渡方向
startProgress:动画起点(在整体动画的百分比)
endProgress:动画终点(在整体动画的百分比)
type :动画类型
基本效果:
kCATransitionFade 渐入渐出效果
kCATransitionMoveIn 移入效果
kCATransitionPush 推入效果
kCATransitionReveal 推出效果
私有API
cube 3D方块
suckEffect 三角
rippleEffect 水波
pageCurl 上翻页
pageUnCurl 下翻页
oglFlip 上下翻转
cameralrisHollowOpen 镜头快门开
cameralrisHollowClose 镜头快门关
示例
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;//设置动画的类型
transition.subtype = kCATransitionFromRight; //设置动画的方向
//anima.startProgress = 0.3;//设置动画起点
//anima.endProgress = 0.8;//设置动画终点
transition.duration = 1.0f;
[self.imageView.layer addAnimation:transition forKey:nil];
最后有一点我还是得说一下,虽然看上去核心动画改变的控件的属性(如frame
,scale
),但是实际控件的真实属性并未被改变,他只是作用在layer
上的。