UIView Animation 动画学习总结
一、前言
动画一直是 iOS 开发中很重要的一部分。设计良好,效果炫酷的动画往往能对用户体验的提升起到很大的作用,在这里将自己学习 iOS 动画的体会记录下来,希望能对别人有所帮助。
iOS 的动画框架,即 CoreAnimation,本身十分庞大和复杂,这里暂时分两个部分进行介绍,分别是 UIView 动画 和 CALayer 动画。
二、UIView Animation
2.1 简单动画
对于 UIView 上简单的动画,iOS 提供了很方便的函数:
animateWithDuration:animations:
- 第一个参数是动画的持续时间,
- 第二个参数是一个 block,在
animations block中对 UIView 的属性进行调整,设置 UIView 动画结束后最终的效果,iOS 就会自动补充中间帧,形成动画。
可以更改的属性有:
frameboundscentertransformalphabackgroundColorcontentStretch
这些属性大都是 View 的基本属性,下面是一个例子,这个例子中的动画会同时改变 View 的 frame,backgroundColor 和 alpha :
[UIView animateWithDuration:2.0 animations:^{
myView.frame = CGRectMake(50, 200, 200, 200);
myView.backgroundColor = [UIColor blueColor];
myView.alpha = 0.7;
}];
其中有一个比较特殊的 transform 属性,它的类型是 CGAffineTransform,即 2D 仿射变换,这是个数学中的概念,用一个三维矩阵来表述 2D 图形的矢量变换。用 transform 属性对 View 进行:
- 旋转
- 缩放
- 其他自定义 2D 变换
iOS 提供了下面的函数可以创建简单的 2D 变换:
CGAffineTransformMakeScaleCGAffineTransformMakeRotationCGAffineTransformMakeTranslation
例如下面的代码会将 View 缩小至原来的 1/4 大小:
[UIView animateWithDuration:2.0 animations:^{
myView.transform = CGAffineTransformMakeScale(0.5, 0.5);
}];
调节参数
完整版的 animate 函数其实是这样的:
animateWithDuration:delay:options:animations:completion:
可以通过 delay 参数调节让动画延迟产生,同时还一个 options 选项可以调节动画进行的方式。可用的 options 可分为两类:
一、控制过程
例如 UIViewAnimationOptionRepeat 可以让动画反复进行, UIViewAnimationOptionAllowUserInteraction 可以让允许用户对动画进行过程中同 View 进行交互(默认是不允许的)
二、控制速度
动画的进行速度可以用速度曲线来表示(参考这里),提供的选项例如 :
UIViewAnimationOptionCurveEaseIn是先慢后快,UIViewAnimationOptionCurveEaseOut是先快后慢。
不同的选项直接可以通过“与”操作进行合并,同时使用,例如:
UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction
2.2 关键帧动画
上面介绍的动画中,我们只能控制开始和结束时的效果,然后由系统补全中间的过程,有些时候我们需要自己设定若干关键帧,实现更复杂的动画效果,这时候就需要关键帧动画的支持了。下面是一个示例:
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat | UIViewKeyframeAnimationOptionAutoreverse animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
self.myView.frame = CGRectMake(10, 50, 100, 100);
}];
[UIView addKeyframeWithRelativeStartTime: 0.5 relativeDuration:0.3 animations:^{
self.myView.frame = CGRectMake(20, 100, 100, 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.2 animations:^{
self.myView.transform = CGAffineTransformMakeScale(0.5, 0.5);
}];
} completion:nil];
这个例子添加了三个关键帧,在外面的 animateKeyframesWithDuration 中我们设置了持续时间为 2.0 秒,这是真实意义上的时间,里面的 startTime 和 relativeDuration 都是相对时间。以第一个为例,startTime 为 0.0,relativeTime 为 0.5,这个动画会直接开始,持续时间为 2.0 X 0.5 = 1.0 秒,下面第二个的开始时间是 0.5,正好承接上一个结束,第三个同理,这样三个动画就变成连续的动画了。
2.3 View 的转换
iOS 还提供了两个函数,用于进行两个 View 之间通过动画换场:
transitionWithView:duration:options:animations:completion:transitionFromView:toView:duration:options:completion:
需要注意的是,换场动画会在这两个 View 共同的父 View 上进行,在写动画之前,先要设计好 View 的继承结构。
同样,View 之间的转换也有很多选项可选,例如
UIViewAnimationOptionTransitionFlipFromLeft从左边翻转,UIViewAnimationOptionTransitionCrossDissolve渐变等等。
三、CALayer Animation

UIView 的动画简单易用,但是能实现的效果相对有限,上面介绍的 UIView 的几种动画方式,实际上是对底层 CALayer 动画的一种封装。直接使用 CALayer 层的动画方法可以实现更多高级的动画效果。
3.1 基本动画(CABasicAnimation)

CABasicAnimation 用于创建一个 CALayer 上的基本动画效果,下面是一个例子:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
animation.toValue = @200;
animation.duration = 0.8;
animation.repeatCount = 5;
animation.beginTime = CACurrentMediaTime() + 0.5;
animation.fillMode = kCAFillModeRemoved;
[self.myView.layer addAnimation:animation forKey:nil];
KeyPath
这里我们使用了 animationWithKeyPath 这个方法来改变 layer 的属性,可以使用的属性有很多,具体可以参考这里和这里。其中很多属性在前面介绍的 UIView 动画部分我们也看到过,进一步验证了 UIView 的动画方法是对底层 CALayer 的一种封装。
需要注意的一点是,上面我们使用了 position 属性, layer 的这个 position 属性和 View 的 frame 以及 bounds 属性都不相同,而是和 Layer 的 anchorPoint有关,可以由下面的公式计算得到:
position.x = frame.origin.x + 0.5 * bounds.size.width;
position.y = frame.origin.y + 0.5 * bounds.size.height;
关于 anchorPoint 和 position 属性的以及具体计算的原理可以参考这篇文章。
属性
·CABasicAnimation 的属性有下面几个:
beginTimedurationfromValuetoValuebyValuerepeatCountautoreversestimingFunction
可以看到,其中 beginTime,duration,repeatCount 等属性和上面在 UIView 中使用到的 duration,UIViewAnimationOptionRepeat等选项是相对应的,不过这里的选项能够提供更多的扩展性。
需要注意的是 fromValue,toValue,byValue 这几个选项,支持的设置模式有下面几种:
- 设置
fromValue和toValue:从 fromValue 变化到 toValue - 设置
fromValue和byValue:从 fromValue 变化到 fromValue + byValue - 设置
byValue和toValue:从 toValue - byValue 变化到 toValue - 设置
fromValue: 从 fromValue 变化到属性当前值 - 设置
toValue:从属性当前值变化到 toValue - 设置
byValue:从属性当前值变化到属性当前值 + toValue
看起来挺复杂,其实概括起来基本就是 :如果某个值不设置,就是用这个属性当前的值。
另外,可以看到上面我们使用的:
animation.toValue = @200;
而不是直接使用 200,因为 toValue 之类的属性为 id 类型,或者像这样使用 @ 符号,或者使用:
animation.toValue = [NSNumber numberWithInt:200];
最后一个比较有意思的是 timingFunction 属性,使用这个属性可以自定义动画的运动曲线(节奏,pacing),系统提供了五种值可以选择:
kCAMediaTimingFunctionLinear线性动画kCAMediaTimingFunctionEaseIn先快后慢kCAMediaTimingFunctionEaseOut先慢后快kCAMediaTimingFunctionEaseInEaseOut先慢后快再慢kCAMediaTimingFunctionDefault默认,也属于中间比较快
此外,我们还可以使用 [CAMediaTimingFunction functionWithControlPoints] 方法来自定义运动曲线,这个网站提供了一个将参数调节可视化的效果,关于动画时间系统的具体介绍可以参考这篇文章。
3.2 关键帧动画(CAKeyframeAnimation)
同 UIView 中的类似,CALayer 层也提供了关键帧动画的支持,CAKeyFrameAnimation 和 CABasicAnimation 都继承自 CAPropertyAnimation,因此它有具有上面提到的那些属性,此外,CAKeyFrameAnimation 还有特有的几个属性。
values 和 keyTimes
使用 values 和 keyTimes 可以共同确定一个动画的若干关键帧,示例代码如下:
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];//在这里@"transform.rotation"==@"transform.rotation.z"
NSValue *value1 = [NSNumber numberWithFloat:-M_PI/180*4];
NSValue *value2 = [NSNumber numberWithFloat:M_PI/180*4];
NSValue *value3 = [NSNumber numberWithFloat:-M_PI/180*4];
anima.values = @[value1,value2,value3];
// anima.keyTimes = @[@0.0, @0.5, @1.0];
anima.repeatCount = MAXFLOAT;
[_demoView.layer addAnimation:anima forKey:@"shakeAnimation"];
可以看到上面这个动画共有三个关键帧,如果没有指定 keyTimes 则各个关键帧会平分整个动画的时间(duration)。
path
使用 path 属性可以设置一个动画的运动路径,注意 path 只对 CALayer 的 anchorPoint 和position 属性起作用,另外如果你设置了 path ,那么 values 将被忽略。
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anima.path = path.CGPath;
anima.duration = 2.0f;
[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];
3.3 动画组(CAAnimationGroup)
组动画可以将一组动画组合在一起,所有动画对象可以同时运行,示例代码如下:
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
//1.基础动画一
CABasicAnimation *animationOne = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animationOne.toValue = @2.0;
animationOne.duration = 1.0;
//2.基础动画二
CABasicAnimation *animationTwo = [CABasicAnimation animationWithKeyPath:@"position.x"];
animationTwo.toValue = @400;
animationTwo.duration = 1.0;
[group setAnimations:@[animationOne, animationTwo]];
[self.myView.layer addAnimation:group forKey:nil];
需要注意的是,一个 group 组内的某个动画的持续时间(duration),如果超过了整个组的动画持续时间,那么多出的动画时间将不会被展示。例如一个 group 的持续时间是 5s,而组内一个动画持续时间为 10s ,那么这个 10s 的动画只会展示前 5s 。
3.4 切换动画(CATransition)
CATransition 可以用于 View 或 ViewController 直接的换场动画:
self.myView.backgroundColor = [UIColor blueColor];
CATransition *trans = [CATransition animation];
trans.duration = 1.0;
trans.type = @"push";
[self.myView.layer addAnimation:trans forKey:nil];
// 这句放在下面也可以
// self.myView.backgroundColor = [UIColor blueColor];
为什么改变颜色放在前后都可以呢?具体的解释可以参考 SO 上的这个回答。简单来说就是动画和绘制之间并不冲突。
四、后记
如果本文对你有一点帮助的话,欢迎收藏、点赞,感谢。文中如有不对之处,也欢迎大家在评论区指出,共勉。
UIView Animation 动画学习总结的更多相关文章
- Android动画学习(二)——Tween Animation
前两天写过一篇Android动画学习的概述,大致的划分了下Android Animation的主要分类,没有看过的同学请移步:Android动画学习(一)——Android动画系统框架简介.今天接着来 ...
- ios基础篇(二十五)—— Animation动画(UIView、CoreAnimation)
Animation主要分为两类: 1.UIView属性动画 2.CoreAnimation动画 一.UIView属性动画 UIKit直接将动画集成到UIView类中,实现简单动画的创建过程.UIVie ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- 转 iOS Core Animation 动画 入门学习(一)基础
iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...
- UIView动画学习笔记
UIView的动画是通过修改控件的属性来达到动画的效果,如:渐变, 移动. 废话不多说,直接上代码: - (void)loadView{ [super loadView]; _leftView = [ ...
- iOS开发给UIView添加动画Animation
self.testView需要添加动画的view 1.翻转动画 [UIView beginAnimations:@"doflip" context:nil]; [UIView se ...
- Swift基础之Animation动画研究
最近研究了一下,Swift语言中关于Animation动画的实现学习,分两次进行相关内容的讲解 用表格列出各种动画情况 Demo首页显示展示了一种动画显示方式,代码如下: //绘画装饰 func ...
- iOS动画学习
学习一下动画,感谢以下大神的文章: UIView:基础动画.关键帧动画.转场动画 Core Animation :基础动画,关键帧动画,动画组,转场动画,逐帧动画 CALayer :CALaye ...
- iOS开发UI篇—核心动画(UIView封装动画)
iOS开发UI篇—核心动画(UIView封装动画) 一.UIView动画(首尾) 1.简单说明 UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画 ...
随机推荐
- 推荐一款M1芯片电脑快速搭建集群的虚拟机软件
虚拟机软件太多了,出名的莫过于VMware,VirutlaBox以及Parallels Desktop. 我们使用虚拟机软件一般有两种用途: 安装不同于宿主机系统的拥有用户界面的操作系统,比如Wind ...
- 设计模式-策略模式前端应用校验vue写法
1.定义:定义一系列算法,把它们一个个封装起来,并且它们可以相互替换 2.实际应用:减少if else的使用,在有多种算法相似的情况下,使用 if-else 所带来的复杂和难以维护,提高维护和可读性, ...
- WPF第三方控件,只能输入数字型数据
话不多说,根据最近项目需求,为了减少输入验证等相关代码量,需要此控件 先上效果图 默认样式是这样,自己可以根据需求修改外形,但我更喜欢它自带的简洁版 有人可能会问怎么实现的呢?其实很简单,我们设置它的 ...
- Pyinstaller打包pikepdf失败的问题排查
问题 最近在项目里用到了pikepdf这个库,用于实现pdf水印插入的一个小功能,源码调试阶段运行一切OK但是在出包时报了如下异常. Traceback (most recent call last) ...
- bat-使用bat安装jdk和配置环境变量
文件路径 @echo off Setlocal enabledelayedexpansion @REM vscode中自动开启延迟环境变量扩展, %~d0 cd %~dp0 @REM dir echo ...
- C++ 练气期之指针所指何处
1. 指针 指针是一种C++数据类型,用来描述内存地址. 什么是内存地址? 内存中的每一个存储单元格都有自己的地址,地址是使用二进制进行编码.地址从形态上看是一个整型数据类型.但是,它的数据含义并不表 ...
- P1189 SEARCH—搜索
将这题加进来的原因 因为他的优化令人眼前一新! 题目传送门() 相似的题目之 血色先锋队 ↑这一题也要用到标记数组 优化!!! 对于一个位置, 如果他在同样的深度再一次被访问,那他接下来所走的路径,所 ...
- C语言-typedef和#define
1.关键字 typedef 为一个数据类型起一个新的别名,typedef 的用法一般为: typedef OldName NewName; 需要强调的是,typedef 是赋予现有类型一个新的名字,而 ...
- JavaScript进阶知识点——函数和对象详解
JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...
- NOI / 2.1基本算法之枚举 1749:数字方格
描述: 如上图,有3个方格,每个方格里面都有一个整数a1,a2,a3.已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍数,a2 + a3是3的倍数, a1 + a2 ...