iOS学习——核心动画
iOS学习——核心动画
1、什么是核心动画
Core Animation(核心动画)是一组功能强大、效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用。核心动画所在的位置如下图所示,可以看到,核心动画位于UIKit的下一层,相比UIView动画,它可以实现更复杂的动画效果。
核心动画作用在CALayer(Core animation layer)上,CALayer的概念、作用以及layer与UIView的区别在上一篇文章中有详细的描述,想了解的朋友可以参见 iOS学习——核心动画之Layer基础,我们可以将UIView看成是一种特殊的CALayer(可以响应事件)。实际上,每一个view都有其对应的layer,这个layer是root layer:
@property (nonatomic, readonly, strong) CALayer *layer;
给view加上动画,本质上是对其layer进行操作,layer包含了各种支持动画的属性,动画则包含了属性变化的值、变化的速度、变化的时间等等,两者结合产生动画的过程。核心动画和UIView动画的对比:UIView动画可以看成是对核心动画的封装,和UIView动画不同的是,通过核心动画改变layer的状态(比如position),动画执行完毕后实际上是没有改变的(表面上看起来已改变)。总体来说核心动画的优点有:
1)性能强大,使用硬件加速,可以同时向多个图层添加不同的动画效果
2)接口易用,只需要少量的代码就可以实现复杂的动画效果。
3)运行在后台线程中,在动画过程中可以响应交互事件(UIView动画默认动画过程中不响应交互事件)。
4)CoreAnimation是跨平台
的,既可以支持IOS,也支持MAC OS
2、核心动画类的层次结构
- CAAnimation是所有动画对象的父类,实现CAMediaTiming协议,负责控制动画的时间、速度和时间曲线等等,是一个抽象类,不能直接使用。
- CAPropertyAnimation :是CAAnimation的子类,它支持动画地显示图层的keyPath,一般不直接使用。
- CASpringAnimation是iOS9.0之后新增的类,它实现弹簧效果的动画,是CABasicAnimation的子类。
- CAAnimationGroup使用Group可以将多个动画合并一起加入到层中,Group中所有动画并发执行,可以方便地实现需要多种类型动画的场景。
- CATransition 主要用于转场动画从一个场景以动画的形式过渡到另一个场景,比如Nav的默认Push视图的效果就是通过CATransition的kCATransitionPush类型来实现。
综上,核心动画类中可以直接使用的类有:
CABasicAnimation
CAKeyframeAnimation
CATransition
CAAnimationGroup
CASpringAnimation
3、 简单使用CoreAnimation的步骤
使用CoreAnimation做动画的时候,遵循四步就好
- 创建CAAnmation子对象,因为CAAnmation是抽象类,所以一般要使用自具体子类,就是上面说的五类
- 设置CAAnmation的属性,不同的动画类别属性参数不一样的
- 调用CALayer的addAnimation:forKey:将CAAnimation对象添加到CALayer上,就能执行动画
- 调用CALayer的removeAnimationForKey方法可以停止CALayer中的动画。
4、CABasicAnimation和CAKeyframeAnimation
CABasicAnimation和CAKeyframeAnimation都是CAPropertyAnimation的子类,这两类动画有着相似的地方,但是也有不同的地方。
- 这两类动画有相似的地方,就是这两类动画都是通过描绘路径来形成动画
- CABasicAnimation通过设定起始点,终点,时间,动画会沿着你这设定点进行移动
- CAKeyFrameAnimation则可以设置路径为更多的点构成的路径,动画会沿着我们设置的多个点进行移动。
- CABasicAnimation可以看成是只有两个点的特殊的CAKeyFrameAnimation动画
这其中主要的参数有:
属性 | 解释 |
---|---|
duration | 动画的持续时间 |
repeatCount | 动画持续次数,最大次数用MAXFLOAT |
repeatDuration | 设置动画的时间,在该时间内动画一直执行,不计次数 |
beginTime | 指定动画开始的时间。从开始延迟几秒的话,设置为CACurrentMediaTime() + 秒数 的方式 |
timingFunction | 设置动画的速度变化 |
fillMode | 动画在开始和结束时的动作,默认值是 kCAFillModeRemoved |
autoreverses | 动画结束时是否执行逆动画 |
fromValue | 所改变属性的起始值(CABasicAnimation独有) |
toValue | 所改变属性的结束时的值(CABasicAnimation独有) |
byValue | 所改变属性相同起始值的改变量(CABasicAnimation独有) |
values |
关键帧数组对象,里面每一个元素即为一个关键帧,动画会在对应的时间段内,依次执行数组中每一个关键帧的动画(CAKeyframeAnimation独有) |
keyTimes |
上面values设定了路径上的关键点,本参数则设定关键点之间的路径段上所需的时间,所以keyTimes的个数应该比values的个数小1(CAKeyframeAnimation独有) |
timingFunctions |
同上keyTimes的含义,及设置每一小段路径上的动画的变化速率(CAKeyframeAnimation独有) |
path | 可以直接设置动画路径(CAKeyframeAnimation独有) |
KeyPath常用的属性:
KeyPath值 | 说明 | 使用形式- swift 3.0 |
---|---|---|
transform.scale | 比例缩放 | 0.8 |
transform.scale.x | 缩放宽的比例 | 0.8 |
transform.scale.y | 缩放高的比例 | 0.8 |
transform.rotation.x | 围绕x轴旋转 | 2 * M_PI |
transform.rotation.y | 围绕y轴旋转 | 2 * M_PI |
transform.rotation.z | 围绕z轴旋转 | 2 * M_PI |
backgroundColor | 背景颜色的变化 | UIColor.red.cgColor |
bounds | 大小缩放,中心不变 | NSValue(cgRect: CGRect(x: 800, y: 500, width: 90, height: 30)) |
position | 位置(中心点的改变) | NSValue(cgPoint: CGPoint(x: 40, y: 240)) |
contents | 内容,比如UIImageView的图片 | UIImage(named: "to")?.cgImage |
opacity | 透明度 | 0.4 |
contentsRect.size.width | 横向拉伸缩放 | 0.6 |
contentsRect.size.height | 纵向拉伸缩放 | 0.5 |
timingFunction主要有五种类别:
- kCAMediaTimingFunctionLinear,在整个动画时间内动画都是以一个相同的速度来改变,也就是匀速运动。一个线性的计时函数,同样也是CAAnimation的timingFunction属性为空时候的默认函数。线性步调对于那些立即加速并且保持匀速到达终点的场景会有意义(例如射出枪膛的子弹)。
- kCAMediaTimingFunctionEaseIn:动画开始时会较慢,之后动画会加速,一个慢慢加速然后突然停止的方法。对于之前提到的自由落体的例子来说很适合,或者比如对准一个目标的导弹的发射。
- kCAMediaTimingFunctionEaseOut:动画在开始时会较快,之后动画速度减慢,它以一个全速开始,然后慢慢减速停止。它有一个削弱的效果,应用的场景比如一扇门慢慢地关上,而不是砰地一声。
- kCAMediaTimingFunctionEaseInEaseOut:动画在开始和结束时速度较慢,中间时间段内速度较快。创建了一个慢慢加速然后再慢慢减速的过程。这是现实世界大多数物体移动的方式,也是大多数动画来说最好的选择。如果只可以用一种缓冲函数的话,那就必须是它了。那么你会疑惑为什么这不是默认的选择,实际上当使用UIView的动画方法时,他的确是默认的,但当创建CAAnimation的时候,就需要手动设置它了。
- kCAMediaTimingFunctionDefault:它和kCAMediaTimingFunctionEaseInEaseOut很类似,但是加速和减速的过程都稍微有些慢。它和kCAMediaTimingFunctionEaseInEaseOut的区别很难察觉,可能是苹果觉得它对于隐式动画来说更适合(然后对UIKit就改变了想法,而是使用kCAMediaTimingFunctionEaseInEaseOut作为默认效果),虽然它的名字说是默认的,但还是要记住当创建显式的CAAnimation它并不是默认选项(换句话说,默认的图层行为动画用kCAMediaTimingFunctionDefault作为它们的计时方法)。
fillMode主要有四种类型:
- kCAFillModeForwards :动画开始之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值是 YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。
- kCAFillModeBackwards :将会立即执行动画的第一帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开始视图不见,还不知道应用在哪里。
- kCAFillModeBoth:该值是 kCAFillModeForwards 和 kCAFillModeBackwards的组合状态
- kCAFillModeRemoved:动画将在设置的 beginTime 开始执行(如没有设置beginTime属性,则动画立即执行),动画执行完成后将会layer的改变恢复原状。
/* CABasicAnimation应用
心跳效果
思路:就是让一张图片做一个放大缩放小的动画.
*/ //代码实现: - (void) viewDidLoad {
CABasicAnimation *anim =[CABasicAnimation animation];
//设置缩放属性
anim.keyPath = @"transform.scale";
//缩放到一半
anim.toValue = @0.5;
//设置动画执行的次数
anim.repeatCount = MAXFLOAT;
//设置动画执行的时长
anim.duration = 0.25;
//设置动画自动反转(怎么去, 怎么回)
anim.autoreverses = YES;
//添加动画
[self.heartView.layer addAnimation:anim forKey:nil];
}
/* CAKeyframeAnimation的应用
图片抖动
思路:其实就是做一个左右旋转的动画.先让它往左边旋转-5,再往右边旋转5度,再从5度旋转到-5度. 就会有左右摇摆的效果了.
*/ //图标抖动代码实现
- (void)values{ //创建一个帧动画
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
//设置属性
anim.keyPath = @"transform.rotation";
//设置属性值.
anim.values = @[@(angle2Rad(-)),@(angle2Rad()),@(angle2Rad(-))];
//设置执行的次数
anim.repeatCount = MAXFLOAT; anim.duration = 0.25; //添加动画
[self.iconV.layer addAnimation:anim forKey:nil]; }
//我们还可以直接设置关键帧CAKeyframeAnimation动画的路径 path属性 -(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{ //创建一个帧动画
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; //设置属性
anim.keyPath = @"position";
//直接设置动画的路径path是画弧
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(, , , )];
anim.path = path.CGPath; //设置执行的次数
anim.repeatCount = MAXFLOAT;
//设置是否反转
anim.autoreverses = YES; anim.duration = ; //添加动画
[self.iconV.layer addAnimation:anim forKey:nil];
}
5、 CATransition转场动画
iOS中实现转场动画有两种方式,一种是通过我们今天学的CATransition转场动画进行,还有一种则是通过UIView的动画进行。CAKeyframeAnimation的重要属性:
type:过渡动画的类型
//转场类型,字符串类型参数.系统提供了四中动画形式:
//kCATransitionFade//淡出效果//kCATransitionMoveIn//新视图移动到旧视图上//kCATransitionPush//新视图推出旧视图//kCATransitionReveal//移开旧视图显示新视图//另外,除了系统给的这几种动画效果,我们还可以使用系统私有的动画效果:
//@"cube",//立方体翻转效果
//@"oglFlip",//翻转效果
//@"suckEffect",//收缩效果,动画方向不可控
//@"rippleEffect",//水滴波纹效果,动画方向不可控
//@"pageCurl",//向上翻页效果
//@"pageUnCurl",//向下翻页效果
//@"cameralIrisHollowOpen",//摄像头打开效果,动画方向不可控
//@"cameraIrisHollowClose",//摄像头关闭效果,动画方向不可控
subtype:设置转场方向
//转场方向,系统一共提供四个方向:
//kCATransitionFromRight//从右开始
//kCATransitionFromLeft//从左开始
//kCATransitionFromTop//从上开始
//kCATransitionFromBottom//从下开始
startProgress:开始进度,默认0.0.如果设置0.3,那么动画将从动画的0.3的部分开始
endProgress:结束进度,默认1.0.如果设置0.6,那么动画将从动画的0.6部分以后就会结束
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
//UIView执行转场动画
[UIView transitionWithView:self.imageV duration: options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ _i++;
if (_i > ) {
_i = ;
}
NSString *imageName = [NSString stringWithFormat:@"%d",_i];
self.imageV.image = [UIImage imageNamed:imageName]; } completion:nil]; }
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{ //转场代码必须得要和转场动画在同一个方法当中.
//创建动画
CATransition *anim = [CATransition animation];
//设置转场类型
anim.type = @"cube";
//设置转场的方向
anim.subtype = kCATransitionFromTop;
//设置动画的开始点.
anim.startProgress = 0.2;
//设置动画的结束点.
anim.endProgress = 0.8; [self.imageV.layer addAnimation:anim forKey:nil]; //转场代码必须得要和转场动画在同一个方法当中.
_i++;
if (_i > ) {
_i = ;
}
NSString *imageName = [NSString stringWithFormat:@"%d",_i];
self.imageV.image = [UIImage imageNamed:imageName];
}
6、CASpringAnimation
CASpringAnimation是iOS9新加入动画类型,是CABasicAnimation的子类,用于实现弹簧动画。CASpringAnimation的重要属性:
- mass:质量(影响弹簧的惯性,质量越大,弹簧惯性越大,运动的幅度越大)
- stiffness:弹性系数(弹性系数越大,弹簧的运动越快)
- damping:阻尼系数(阻尼系数越大,弹簧的停止越快)
- initialVelocity:初始速率(弹簧动画的初始速度大小,弹簧运动的初始方向与初始速率的正负一致,若初始速率为0,表示忽略该属性)
- settlingDuration:结算时间(根据动画参数估算弹簧开始运动到停止的时间,动画设置的时间最好根据此时间来设置)
- (void)springAni {
CASpringAnimation * ani = [CASpringAnimation animationWithKeyPath:@"bounds"];
ani.mass = 10.0; //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
ani.stiffness = ; //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
ani.damping = 100.0;//阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
ani.initialVelocity = .f;//初始速率,动画视图的初始速度大小;速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
ani.duration = ani.settlingDuration;
ani.toValue = [NSValue valueWithCGRect:self.centerShow.bounds];
ani.removedOnCompletion = NO;
ani.fillMode = kCAFillModeForwards;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.cartCenter.layer addAnimation:ani forKey:@"boundsAni"];
}
7、CAAnimationGroup
使用Group可以将多个动画合并一起加入到层中,Group中所有动画并发执行,可以方便地实现需要多种类型动画的场景。
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{ CAAnimationGroup *group = [CAAnimationGroup animation]; //缩放
CABasicAnimation *scaleAnim = [CABasicAnimation animation];
//设置属性
scaleAnim.keyPath = @"transform.scale";
scaleAnim.toValue = @0.5; //平移
CABasicAnimation *Anim = [CABasicAnimation animation];
//设置属性
Anim.keyPath = @"position.y";
Anim.toValue = @(); //将上面两个动画添加到动画组
group.animations = @[scaleAnim,Anim]; //设置动画的属性,一定要在动画组上设置
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
//添加动画
[self.redView.layer addAnimation:group forKey:nil]; }
参考资料:
iOS动画-从不会到熟练应用
iOS学习——核心动画的更多相关文章
- iOS学习——核心动画之Layer基础
iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...
- IOS QuartzCore核心动画框架
IOS QuartzCore核心动画框架 核心动画框架 使用核心动画需要引入的框架:#import CALayer: CoreAnimation CALayer就是UIView上的图层,很多的CALa ...
- iOS:核心动画的详解介绍:CAAnimation(抽象类)及其子类
核心动画的详解介绍:CAAnimation(抽象类) 1.核心动画基本概念 Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍! 使用它 ...
- iOS之核心动画(Core Animation)
Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就可以实现非常强大的功能. Core ...
- iOS基础 - 核心动画
一.核心动画 l 核心动画基本概念 l 基本动画 l 关键帧动画 l 动画组 l 转场动画 l Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事 ...
- iOS:核心动画之基本动画CABasicAnimation
基本动画,是CAPropertyAnimation的子类 属性说明: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 动画过程说明: 随着动画的进行 ...
- iOS:核心动画具体的类和协议的介绍
核心动画类:CAAnimation.CAPropertyAnimation.CABasicAnimation.CAKeyframeAnimation.CATransition.CAAnimationG ...
- iOS开发-核心动画随笔
核心动画可以让View旋转,缩放,平移(主要是操作View的layer(层)属性)但是核心动画改变的位置不是真实的位置,一切都是假象所以有时候要用到其他动画,如UIView本来封装的动画,还有定时器 ...
- iOS之核心动画
.将动画的所有方法封装到一个类里面 MyCAHelper.h #import <Foundation/Foundation.h> #import <QuartzCore/Quartz ...
随机推荐
- P1113 杂务 拓扑排序
题目描述 John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作.尽早将所有杂务完成是必要的,因为 ...
- symfony简单的博客练习,熟悉具体开发流程
这里搭建一个简单的博客系统作为练习,之后再完成学校任务搭建一个表白墙, 使用htmlpurifier和parsedown来搭建前端,所以需要先安装这两个第三方包,必须要弄一个composer的国内镜像 ...
- IO流2
一.IO流简介及分类 1.IO流简介 IO流: 简单理解数据从一个地方流向另外一个地方 2.IO流分类 按照数据流动的方向 分为 输入流和输出流 按照数据流动的单位分为 字节流和字符流 二.四大 ...
- python3_猜数字
import random count = 0while count<3: count +=1 number = int(input("猜数字:").strip()) num ...
- 四、自动化平台搭建-Django-如何做验证码
前提:安装包 pip install pillow==3.4.1 1.打开booktest/views.py,创建视图verify_code. from PIL import Image, Ima ...
- BUAA面向对象设计与构造——第二单元总结
BUAA面向对象设计与构造——第二单元总结 第一阶段:单部傻瓜电梯的调度 第二阶段:单部可捎带电梯的调度 (由于我第一次写的作业就是可捎带模式,第二次只是增加了负数楼层,修改了一部分参数,因此一起总结 ...
- CentOS7配置mailx使用外部smtp服务器发送邮件
转自huskiesir的博客: 发送邮件的两种方式: 1.连接现成的smtp服务器去发送(此方法比较简单,直接利用现有的smtp服务器比如qq.新浪.网易等邮箱,只需要直接配置mail.rc文件即可实 ...
- 印象笔记 MAC安装使用旧版本
印象笔记终于支持markdown了,赞! 第一个beta版用起来非常不错.提示更新安装新版本后保存markdown一直提示 "Note content is invalid.",无 ...
- Analysis CDI
CDI是一组服务,它们一起使用,使开发人员可以轻松地在Web应用程序中使用企业bean和JavaServer Faces技术.CDI设计用于有状态对象,还有许多更广泛的用途,允许开发人员以松散耦合但类 ...
- 论python中的函数参数的传递问题。
python是完全面向对象的语言,在参数传递的过程不能使用值传递,引用传递的概念,而应该使用immutable和mutable.在java中,除了object,其实还有8种基本数据类型,才有了参数传递 ...