Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。

Core Animation可以用在Mac OS X和iOS平台。

Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

一、CALayer与UIView的关系

在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。

其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层:

在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层。

@property(nonatomic,readonly,retain) CALayer *layer;

在ViewController中可以直接使用self.view.layer

当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示。

二、UIView动画简介

UIView动画可以设置的动画属性有:

  • 大小变化(frame)
  • 拉伸变化(bounds)
  • 中心位置(center)
  • 旋转(transform)
  • 透明度(alpha)
  • 背景颜色(backgroundColor)
  • 拉伸内容(contentStretch)

三、Core Animation结构

626233-43bafe84d8aee5bf.png

其中灰色虚线表示继承关系,红色表示遵守协议。

核心动画中所有类都遵守CAMediaTiming协议。

CAAnaimation是个抽象类,不具备动画效果,必须用它的子类才有动画效果。

CAAnimationGroup和CATransition才有动画效果,

CAAnimationGroup是个动画组,可以同时进行缩放,旋转(同时进行多个动画)。

CATransition是转场动画,界面之间跳转(切换)都可以用转场动画。

CAPropertyAnimation也是个抽象类,本身不具备动画效果,只有子类才有。

CABasicAnimation和CAKeyframeAnimation:

CABasicAnimation基本动画,做一些简单效果。

CAKeyframeAnimation帧动画,做一些连续的流畅的动画。

四、Core Animation的使用

更多基础的详细的介绍可以参考文章最后的文章,后面的这几个文章都写的很不错,就不重复造轮子了,这里主要说下怎么使用。

4.1、最原始的使用

//原始变色 [UIView beginAnimations:@"test" context:nil]; [UIView setAnimationDuration:2.0f]; [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; self.view.backgroundColor = [UIColor redColor]; [UIView commitAnimations];

使用beginAnimations标记动画开始,里面可以设置各种参数,比如setAnimationDuration动画时长等

4.2、也可以使用block块

//使用block块变色 [UIView animateWithDuration:2.0f animations:^{ [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; self.view.backgroundColor = [UIColor redColor]; }];

4.3、使用CABasicAnimation来变色

CABasicAnimation是基本动画,通过fromvalue和tovalue来实现开始和结束的动画值

属性说明
fromValuekeyPath相应属性的初始值
toValuekeyPath相应属性的结束值

动画过程说明:

随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue。

keyPath内容是CALayer的可动画Animatable属性,比如位置position、背景颜色backgroundColor

同时setRemovedOnCompletion和setFillMode同时设置,来实现结束状态是什么样子

//结束后保持状态 [baseAnimation setRemovedOnCompletion:NO]; [baseAnimation setFillMode:kCAFillModeForwards];

那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变

//使用CABasicAnimation变色 CABasicAnimation *baseAnimation = [CABasicAnimation animation]; [baseAnimation setKeyPath:@"backgroundColor"]; //结束后保持状态 [baseAnimation setRemovedOnCompletion:NO]; [baseAnimation setFillMode:kCAFillModeForwards]; //更改位置可以这样设置 // [baseAnimation setKeyPath:@"position"]; // [baseAnimation setFromValue:[NSValue valueWithCGRect:CGRectMake(0, 200, 100, 100)]]; // [baseAnimation setToValue:[NSValue valueWithCGRect:CGRectMake(0, 400, 100, 100)]]; [baseAnimation setToValue:(id)[UIColor redColor].CGColor]; [self.view.layer addAnimation:baseAnimation forKey:@"ss"];

这样,就达到了同样的效果。

4.4、groupAnimation动画组的使用

groupAnimation动画组可以使这几个动画同时运行显示,默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间。

比如这里把背景颜色、位置、旋转度同时设置,可以这么用

//使用动画组groupAnimation,组合动画同时运行 CABasicAnimation *baseAnimation = [CABasicAnimation animation]; [baseAnimation setKeyPath:@"backgroundColor"]; [baseAnimation setToValue:(id)[UIColor redColor].CGColor]; CABasicAnimation *baseAnimation2 = [CABasicAnimation animation]; [baseAnimation2 setKeyPath:@"position"]; [baseAnimation2 setToValue:[NSValue valueWithCGRect:CGRectMake(0, 200, 100, 100)]]; CABasicAnimation *baseAnimation3 = [CABasicAnimation animation]; [baseAnimation3 setKeyPath:@"transform.rotation.y"]; [baseAnimation3 setToValue:[NSNumber numberWithDouble:M_PI*200]]; CAAnimationGroup *groupAniation = [[CAAnimationGroup alloc] init]; [groupAniation setAnimations:[NSArray arrayWithObjects:baseAnimation,baseAnimation2,baseAnimation3, nil]]; [groupAniation setDuration:2.0f]; [groupAniation setRepeatCount:1]; [groupAniation setRemovedOnCompletion:NO]; [groupAniation setFillMode:kCAFillModeForwards]; [self.view.layer addAnimation:groupAniation forKey:@"ss"];

4.5、CATransition转场动画的使用

CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点。

UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果。

比如这里使用转场动画来操纵一个UIView,这里的self.m_addView加的有一个图片和一个按钮

self.m_addView = [[UIView alloc] initWithFrame:CGRectMake(10, 400, 300, 300)]; [self.m_addView setHidden:true]; [self.view addSubview:self.m_addView]; UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)]; imgView.image = [UIImage imageNamed:@"1.png"]; [self.m_addView addSubview:imgView]; UIButton *doneBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, 100, 40)]; [doneBtn setTitle:@"D O N E" forState:UIControlStateNormal]; [doneBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; [doneBtn addTarget:self action:@selector(endTransformAction) forControlEvents:UIControlEventTouchUpInside]; [self.m_addView addSubview:doneBtn];

点击按钮时,开始做一个翻页的动画

[self.m_addView setHidden:false]; [UIView beginAnimations:@"FlipAni" context:nil]; [UIView setAnimationDuration:1.0]; [UIView setAnimationDelegate:self]; //可以设置开始的回调函数 // [UIView setAnimationWillStartSelector:@selector(startAni:)]; //可以设置结束完成的回调函数 // [UIView setAnimationDidStopSelector:@selector(stopAni:)]; [UIView setAnimationRepeatCount:1]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.m_addView cache:NO]; [UIView commitAnimations];

这样就可以了,当然也可以使用block块来实现同样的目的

//block块转场动画 [self.m_addView setHidden:false]; [UIView transitionWithView:self.m_addView duration:1.0 options:UIViewAnimationOptionTransitionCurlUp animations:^{ [UIView setAnimationRepeatCount:1]; } completion:^(BOOL finished) { if (finished) { NSLog(@"compltion"); } }];

这几个就是最基础的使用,当然core Animation是很强大的,操作layer层。如果需要深入了解原理,可以看后面的参考文章。

五、demo下载

Github下载:https://github.com/DamonHu/HudongBlogDemo/tree/master/LayerTransformDemo

Gitosc下载:http://git.oschina.net/DamonHoo/LayerTransformDemo

六、参考文章


☟☟可点击下方广告支持一下☟☟

最后修改:2021 年 03 月 07 日
请我喝杯可乐,请随意打赏: ☞已打赏列表