核心动画
- 动画可以大致分为两种,一种是UIView上的,一种是CALayer层的,其实本质都是基于CoreAnimation框架下,CALayer层的被称为核心动画,功能更强大,UIView的动画是基于核心动画的封装,用起来更加方便,由于CALayer层的核心动画是QuartzCore框架中的,可移植性高,OSX和ios上都可以用,但是在开发过程中用到的UIColor、UIImage是定义在UIKit框架中的,只能在iOS中使用,也就意味着利用核心动画的时候需要转换成CoreGraphics框架下的数据类型(即CGImageRef、CGColorRef)
UIView上的动画
UIImageView的动画(gif动画)
//UIImageView的动画
- (void)gif
{
NSMutableArray *arrayData = [NSMutableArray array];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
for (int i = 0; i < 31; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",(i + 1)]];
[arrayData addObject:image];
}
//播放的图片
self.imageView.animationImages = arrayData;
//播放时间
self.imageView.animationDuration = 1;
//播放次数
self.imageView.animationRepeatCount = INT_MAX;
//开始播放
[self.imageView startAnimating];
//添加
[self.view addSubview:self.imageView];
}
系统提供的风火轮动画(菊花)
//系统提供的菊花
- (void)activityIndicatorView
{
//菊花
self.acView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.acView.center = self.view.center;
[self.view addSubview:self.acView];
//修改颜色
self.acView.color = [UIColor grayColor];
//开始播放
[self.acView startAnimating];
//停止菊花
self.acView.hidesWhenStopped = NO;
//停止播放
// [self.acView stopAnimating];
}
block动画(最简单最常用的动画,以animateWith开头,带有一个block)
//最常用最简单的动画(block方法)
- (void)blockView
{
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
self.view.backgroundColor = [UIColor yellowColor];
//1.动画的执行时间 2.动画的执行结果 3. 动画的执行完毕回调
[UIView animateWithDuration:3 animations:^{
self.view.backgroundColor = [UIColor redColor];
coustomView.frame = CGRectMake(50, 50, 80, 20);
} completion:^(BOOL finished) {
//完成之后会来到这里
NSLog(@"动画执行完毕");
}];
}
与block效果一样的动画,创建方式不同(方法基本是对应的)
//跟block是对应的,效果是相同的,只是方式不一样
- (void)UIView
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//开始动画(id用来区分多个动画)
[UIView beginAnimations:@"动画的id" context:@"附加的值"];
//设置动画的属性(设置动画的属性一定要在开始动画和提交动画之间写)
//时间
[UIView setAnimationDuration:2];
//动画的次数
[UIView setAnimationRepeatCount:1];
//(重复之后回去的渐变效果)
[UIView setAnimationRepeatAutoreverses:YES];
//设置动画的延迟时间
[UIView setAnimationDelay:1.0];
//设置代理
[UIView setAnimationDelegate:self];
//动画将要开始的时候执行的方法
[UIView setAnimationWillStartSelector:@selector(startAction:context:)];
//动画结束的时候执行的方法
[UIView setAnimationDidStopSelector:@selector(stopAction:context:)];
//运动轨迹
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//设置动画的最终结果
coustomView.backgroundColor = [UIColor redColor];
//提交动画
[UIView commitAnimations];
}
//开始执行的方法
- (void)startAction:(id)sender context:(id)context
{
NSLog(@"%@ %@",sender,context);
}
//结束执行的方法
- (void)stopAction:(id)sender context:(id)context
{
NSLog(@"%@ %@",sender,context);
}
关键帧动画(可以添加多个帧完成动画,多个帧意味着UIView的多个形态)
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//关键帧动画
[UIView animateKeyframesWithDuration:5 delay:1 options:UIViewKeyframeAnimationOptionRepeat animations:^{
//加了两个关键帧 , startTime是开始的时间,但是关键帧里的时间都是要乘以总时间的,也就是第一个帧的开始时间肯定为0,第二帧的开始时间应该是第一帧结束,relativeDuration是指本帧运行的时间,也就是说两个帧的运行时间加起来要等于1
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
coustomView.frame = CGRectMake(300, 300, 50, 50);
}];
[UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
coustomView.frame = CGRectMake(100, 500, 100, 100);
}];
} completion:^(BOOL finished) {
}];
spring动画(也就是弹簧效果+动画曲线)
//弹簧效果+动画曲线
- (void)springView
{
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//1.运行的时间 2.延迟 3.弹簧效果0-1(1是不弹) 4.初始速率 5.动画的模式(枚举)
[UIView animateWithDuration:2 delay:1 usingSpringWithDamping: 0.1 initialSpringVelocity:12 options:UIViewAnimationOptionRepeat animations:^{
coustomView.frame = CGRectMake(100, 400, 50, 50);
} completion:^(BOOL finished) {
}];
}
CALayer层的动画(CoreAnimation)
- CoreAnimation是直接作用于layer层的动画
- 开发步骤:
- 1.首先得有CALayer
- 2.初始化一个CAAnimation对象,并设置一些动画相关属性
- 3.通过调用CALayer的addAnimation:forKey:方法,增加CAAnimation对象到CALayer中,这样就能开始执行动画了
- 4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
- 隐式动画: 所有的非主层的layer,也就是手动创建的layer,都存在隐式动画,当对layer的部分属性(也就是注释中带有Animatable字样的)进行修改时会默认自动产生一些动画效果
CALayer概述
- 在ios中所有能看见的控件都是UIView,但其实UIView是不能显示东西的,完全是因为layer层的原因,每一个UIView控件都至少有一个layer层(主层),主层是系统帮我们创建好的,但是我们可以在UIView上添加其他的layer层
- CALayer显示原理:当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示
- CALayer的基本用法
//layer的属性和动画(只要被Animatable修饰的属性都可以动画)
- (void)layer
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:coustomView];
//设置了layer的背景颜色
coustomView.layer.backgroundColor = [UIColor redColor].CGColor;
//设置layer描边的颜色
coustomView.layer.borderColor = [UIColor yellowColor].CGColor;
//设置layer描边的宽度
coustomView.layer.borderWidth = 10.0f;
//圆角的半径
coustomView.layer.cornerRadius = 10;
//阴影的颜色
coustomView.layer.shadowColor = [UIColor blackColor].CGColor;
//阴阳的偏移量
coustomView.layer.shadowOffset = CGSizeMake(-5, -5);
//阴影的透明度
coustomView.layer.shadowOpacity = 0.5;
//阴影的模糊成都
coustomView.layer.shadowRadius = 3;
[UIView animateWithDuration:2 animations:^{
//旋转 1.旋转的角度 2.x轴是否转(0或1),3.y轴是否转(0或1),4.z轴是否转(0或1)
coustomView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
//缩放 1.x缩放的比例 2.y缩放的比例3.z缩放的比例(没效果)
coustomView.layer.transform = CATransform3DMakeScale(0, 0, 0);
//平移的距离 1.x平移距离 2.y平移距离 3.z平移距离(没效果)
coustomView.layer.transform = CATransform3DMakeTranslation(100, 100, 100);
}];
//给UIView添加额外的layer层
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor cyanColor].CGColor;
[coustomView.layer addSublayer:layer];
}
- CALayer的position和anchorPoint属性
- position:用来设置layer在父层中的位置,以父层的左上角为原点(0,0)
- anchorPoint:称为锚点,是layer上的哪个点在position属性所指的位置显示,范围是(0,0)- (1,1),默认是(0.5,0.5)
- 例如:position设置为(0,0),锚点不设置,也就是说layer的中心会放到(0,0)点,layer只显示了layer的1/4(右下角)
- (void)layerbuchong
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:coustomView];
CALayer *layer = [[CALayer alloc] init];
//layer的位置相对于锚点的
layer.position = CGPointMake(0, 0);
//锚点,默认0.5,0.5;
layer.anchorPoint =CGPointMake(0, 0);
layer.backgroundColor = [UIColor yellowColor].CGColor;
layer.frame = CGRectMake(0, 0, 100, 100);
[coustomView.layer addSublayer:layer];
}
转场动画
- 为layer层提供进入屏幕和移出屏幕的动画效果
- 重要属性:
- type:动画过渡类型
- subtype:动画过渡方向
- startProgress:动画起点(在整体动画的百分比)
- endProgress:动画终点(在整体动画的百分比)
- 系统给出的转场动画的type的样式
static int i = 2;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 转场代码
if (i == 4) {
i = 1;
}
// 加载图片名称
NSString *imageN = [NSString stringWithFormat:@"%d",i];
_imageView.image = [UIImage imageNamed:imageN];
i++;
// 转场动画(一定要和想要转场的代码放到一起)
CATransition *anim = [CATransition animation];
//动画过度的样式
anim.type = @"pageCurl";
//时间
anim.duration = 2;
//添加动画
[_imageView.layer addAnimation:anim forKey:nil];
}
方法 |
说明 |
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; |
使用UIView动画函数实现转场动画——单视图 duration:动画的持续时间 view:需要进行转场动画的视图 options:转场动画的类型 animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block |
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion; |
使用UIView动画函数实现转场动画——双视图 duration:动画的持续时间 options:转场动画的类型 animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block |
CABaseAnimation
- 基础动画,通过设置keypath模仿KVC的形式去改变layer的某个属性,但是一次只能修改一个
- 动画过程:随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐的变为toValuekeyPath内容是CALayer的可动画Animatable属性如果fillMode=kCAFillModeForwards同时removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
- (void)baseAnimation
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
coustomView.backgroundColor = [UIColor redColor];
//设置锚点
coustomView.layer.anchorPoint = CGPointMake(0, 0);
[self.view addSubview:coustomView];
//创建CABasicAnimation
CABasicAnimation *baseAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
//初始值(属性的最初值)
baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
//结束值(绝对的)
// baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(20, 20)];
//结束值(相对的)
baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(- 80, - 80)];
//时间
baseAnimation.duration = 2.0;
//最终的位置
coustomView.layer.position = CGPointMake(20, 20);
//为layer层添加动画,后面的key可以传空,没用
[coustomView.layer addAnimation:baseAnimation forKey:@"1"];
}
CAKeyframeAnimation
- 关键帧动画,与UIView的关键帧动画模式一样,但也是通过基础动画的方式改变layer的某个属性
- 主要属性的说明:
- values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
- path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
- keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
- CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation
//关键帧动画
- (void)CAKeyframeAnimation
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
coustomView.backgroundColor = [UIColor redColor];
coustomView.layer.anchorPoint = CGPointMake(0, 0);
[self.view addSubview:coustomView];
//关键帧动画
CAKeyframeAnimation *key = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGPoint point1 = CGPointMake(40,0);
CGPoint point2 = CGPointMake(80,0);
CGPoint point3 = CGPointMake(80,40);
CGPoint point4 = CGPointMake(80,80);
//关键帧的值
key.values = @[[NSValue valueWithCGPoint:point1],[NSValue valueWithCGPoint:point2],[NSValue valueWithCGPoint:point3],[NSValue valueWithCGPoint:point4]];
//添加时间
key.duration = 10;
//设置每一帧的运行时间
key.keyTimes = @[@(0.7),@(0.1),@(0.1)];
coustomView.layer.position = CGPointMake(80, 80);
//添加动画
[coustomView.layer addAnimation:key forKey:@"1"];
}