Core Animation,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。在后台移动图层中的内容, 执行完毕后图层本身的位置并没有发生变化,所有的动画都继承自CAAnimation。iOS开发中实现动画的方式也不只是核心动画一种,也有UIView的几种动画。
一、核心动画
Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。所以,CALayer是核心动画的基础。
创建动画的流程一般为:
1、创建动画对象;2、设置动画属性;3、把动画对象添加到某个CALayer 对象上;4、需要停止动画:可以调用 remove 方法移除动画。
动画类型有:
1、 属性动画:设定某个属性的值,可以实现属性动画。2、基本动画(CABasicAnimation):设定某个属性从某个值到某个值,实现基本动画。
3、关键帧动画(CAKeyframeAnimation):设定某个属性的值从某个值到某个值,再到某个值。按照关键值改变的顺序,实现动画。
4、 组动画(CAAnimationGroup):把所有其他的动画添加到组里面,这样就可以按照添加的动画一次执行。
5、 转场动画(CATransition):从一个场景转换到另一个场景,系统已经实现好了,不需要我们再去写,按照需求直接调用。
1、CAAnimation
所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类。
属性有:1、duration(动画的持续时间,默认是0.25s) 2、repeatCount(动画重复次数) 3、repeatDuration(动画重复时间) 4、removedOnCompletion(默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。) 5、fillMode(决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后)6、beginTime(可以用来设置动画延迟执行时间)7、timingFunction(速度控制函数,控制动画运行的节奏)
它还有一个隐式代理delegate,可以监听动画开始 -(void)animationDidStart:(CAAnimation *)anim ,监听动画结束 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
2、CAPropertyAnimation(CAAnimation的子类)
它本身也是一个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation。
重要属性keyPath:将CALayer的一个属性名称作为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@”position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果。
一、CABasicAnimation 基本动画
有fromValue和toValue两个重要属性,随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue,如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0)。
例子:1、按路径移动(基本动画)
一、先创建动画对象,设置keypath CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];意思是沿着x轴平移
二、设置起始值和到达值 animation.fromValue= @(150); animation.toValue = @(-150); animation.duration=1;
三、添加到layer [self.button.layer addAnimation:animation forKey:nil];
2、旋转(基本动画)
一、先创建动画对象 设置keypath CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];意思是沿着y轴旋转
二、设置属性值 NSNumber * num = @(M_PI*2); animation.toValue=num; animation.removedOnCompletion=NO;animation.fillMode=kCAFillModeForwards;
animation.duration=3;animation.repeatCount=CGFLOAT_MAX;
三、添加到layer [self.button.layer addAnimation:animation forKey:nil];
二、CAKeyframeAnimation 关键帧动画
关键帧动画是多个值之间的变化实现动画的,有 values属性:关键帧数组,动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧;path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略;keyTimeshare:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的。
例子:1、按方形路径移动
一、创建动画对象,设置keypath CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
二、设置values,NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(300, 400)]; NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
animation.values=@[v1,v2,v3,v4,v5];
animation.duration=2;
animation.repeatCount=CGFLOAT_MAX;
animation.removedOnCompletion=NO;
三、添加到layer [self.button.layer addAnimation:animation forKey:nil];
2、size变化
一、创建动画对象 CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];
二、设置values NSValue * v0 = [NSValue valueWithCGSize:CGSizeMake(100, 100)]; NSValue * v1 = [NSValue valueWithCGSize:CGSizeMake(200, 200)];
NSValue *v2 = [NSValue valueWithCGSize:CGSizeMake(100,100)];
animation.values=@[v0,v1,v2];animation.duration=0.5;animation.repeatCount=CGFLOAT_MAX;
animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards;
三、添加layer [self.button.layer addAnimation:animation forKey:nil];
基本动画和关键帧动画的区别在于CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值。CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation。
三、CAAnimationGroup 组动画
可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。有属性animations:用来保存一组动画对象的NSArray,默认情况下一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画开始的时间
例子:移动动画+抖动动画
一、创建动画对象
CAKeyframeAnimation * animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
二、设置属性,如上面的按方形移动
三、创建抖动动画对象,keypath为rotation.z
四、设置抖动动画对象的属性
五、创建组动画 CAAnimationGroup * animation = [CAAnimationGroup animation]; animation.animations=@[animation1,animation2];
六、将组动画添加到layer [self.button.layer addAnimation:animation forKey:nil];
四、CATransition 转场动画
用于做页面跳转时的转场动画,能够为层提供移出屏幕和移入屏幕的效果,这些动画的效果系统已经写好,我们只要配置一些属性即可。
属性解析:1、type:动画过渡类型;2、subtype:动画过渡方向;3、startProgress:动画起点(在整体动画的百分比);4、endProgress:动画终点(在整体动画的百分比)
例子:背景是界面上有一个UIImageview,添加了左滑和右滑手势,左右滑动实现UIImageview内容变化
1、使用CATransition实现转场(渐变消失)
一、创建动画 CATransition * animation = [CATransition animation];
二、属性设置 animation.type = kCATransitionFade;(前一张消失)
三、添加到layer [self.imageView.layer addAnimation:animation forKey:nil];
2、使用UIView(block)实现转场(向左拖:左右旋转+ 向右拖:上下翻页)
//如果向左滑动,向左旋转显示
if (rec.direction==UISwipeGestureRecognizerDirectionLeft) {
[UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
//block里面是控件的属性变化,这里和CATransition实现不同
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
self.imageView.image=image;
} completion:nil];
}
//如果向右滑动,子页面向下推出
else{
[UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
self.imageView.image=image;
} completion:nil];
}
}
3、使用CATransition实现转场(向左滑:向左退出 + 向右滑:向下推出)
CATransition * animation = [CATransition animation];
//如果向右滑动,子页面从左推出
if (rec.direction == UISwipeGestureRecognizerDirectionRight) {
animation.subtype = kCATransitionFromBottom;
}
//如果向右滑动,子页面从下推出
else{
animation.subtype = kCATransitionFromRight;
}
animation.type = kCATransitionPush;
[self.imageView.layer addAnimation:animation forKey:nil];
五、UIView block动画———(也可实现转场动画)
UIKit框架直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持。将改变视图属性的代码写在block中,实现动画。有三种方式:
1、+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 其中,delay:动画延迟delay秒后开始,options:动画的节奏控制
2、+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 其中,view是需要进行转场动画的视图
3、+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion 这个方法调用后相当于添加toview到父视图 [fromView.superview addSubview:toView]; ,把fromView从父视图中移除[fromView.superview removeFromSuperview];
六、UIView 首尾式动画
这是UIView的另一种实现动画方式。执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之间,俗称首尾式动画。常见的方法有:
1、设置动画代理对象,当动画开始或者结束时会发消息给代理对象 + (void)setAnimationDelegate:(id)delegate
2、当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector + (void)setAnimationWillStartSelector:(SEL)selector
3、当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector + (void)setAnimationDidStopSelector:(SEL)selector
4、动画的持续时间,秒为单位 + (void)setAnimationDuration:(NSTimeInterval)duration
5、动画延迟delay秒后再开始 + (void)setAnimationDelay:(NSTimeInterval)delay
6、动画的开始时间,默认为now + (void)setAnimationStartDate:(NSDate *)startDate
7、动画的节奏控制 + (void)setAnimationCurve:(UIViewAnimationCurve)curve
8、动画的重复次数 + (void)setAnimationRepeatCount:(float)repeatCount
9、如果设置为YES,代表动画每次重复执行的效果会跟上一次相反 + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses
10、设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好 + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache
七、UIImageView的帧动画
UIImageView可以让一系列的图片在特定的时间内按顺序显示。
属性解析:
1、animationImages:要显示的图片(一个装着UIImage的NSArray)
2、animationDuration:完整地显示一次animationImages中的所有图片所需的时间
3、animationRepeatCount:动画的执行次数(默认为0,代表无限循环)
八、UIActivityIndicatorView 转轮动画
是一个旋转进度轮,可以用来告知用户有一个操作正在进行中,一般用initWithActivityIndicatorStyle初始化