iOS动画原理
1. iOS动画原理
- 本质:动画对象(这里是
UIView
)的状态,基于时间变化的反应 - 分类:可以分为显式动画(关键帧动画和逐帧动画)和隐式动画
- 关键帧和逐帧总结:关键帧动画的实现方式,只需要修改某个属性值就可以了,简单方便,但涉及的深层次内容较多,需要更多的理解和练习。采用逐帧动画的实现方式,实现原理简单,但绘制动画的过程要复杂。如果动画过程处理的事情较多,也会带来较大的开销,就有可能造成动画帧数的下降,出现卡顿的现象,因此需要较多的测试和调试。
1.1 显式动画(逐帧动画和关键帧动画)
显式动画本质是我们显式地给
CALayer
添加一个动画
逐帧动画
- 用户需要
周期性
的调用绘制
方法,绘制每帧的动画对象,系统操作方法简单,但用户操作的工作量就会大一些 周期性
这边指的是定时器CADisplayLink
,其基于屏幕刷效率的,即屏幕每次刷新时就会触发调用(iPhone为60FPS)。绘制
指的是对UIView
背后对应的主CALayer
进行的修改,这边的修改包括- drawRect:
方法和UIView
的属性渐变(改变颜色尺寸等)。- 注意1:因为有些时候绘制过程相对复杂,所以一般采用每隔一帧进行绘制,相当于30FPS的刷新率。另外著名的pop动画框架,就是用
CADisplayLink
进行的逐帧动画。 - 注意2:如果在逐帧绘制的方法中修改了一个自建的
CALayer
,这个CALayer
不是对应某个UIView
的,需注意系统的隐式动画
的影响,后面会提到这点。
- 用户需要
关键帧动画
- 主要是使用两个关键帧---起始帧和结束帧,再配合别的关键信息(如动画时间和运动类型等)
- 每个
CALayer
都有一个属性来表示成坐标,我们可以修改模型层modelLayer
来改变展现层presentationLayer
来形成动画效果。 - 整个动画过程,通过坐标层次来看如下所示:
- 动画前,显示模型层的当前值;
- 动画开始,切换显示展现层的值;
- 动画过程中,展现层的值根据时间变化,我们看到的实际是展现层的值在变化;
- 动画结束,切换回显示模型层的值,此时模型层的值应被修改为动画结束时的值。
- 代码注释如下:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view]; // CABasicAnimation指定一个keyPath,详见官方API
// 常见keyPath:transform.scale/transform.translation.x/position.x(非3D平移)
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
// 开始帧
animationWithKeyPath.fromValue = @(100);
// 结束帧
animationWithKeyPath.fromValue = @(200);
// 动画时间
animation.duration = 2.0;
// 永久重复动画
animation.repeatCount = HUGE;
// 代理方法:
// - (void)animationDidStart:(CAAnimation *)anim;
// - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
animation.delegate = self;
// fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
animation.fillMode = kCAFillModeForwards;
// removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
animation.removedOnCompletion = NO;
// autoreverses:动画结束时是否执行逆动画
animation.autoreverses = NO;
// timingFunction:动画类型,设定动画的速度变化
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// 给CALayer添加一个动画,该动画为CAAnimation类型,其子类有CABasicAnimation/CAKeyframeAnimation/CAAnimationGroup/CATransition(图层过度动画,有filter属性)
[view.layer addAnimation:animation forKey:nil];
1.2 隐式动画
当前
UIView
的主CALayer
称为根层,自动另外创建的CALayer
为非根层,对非根层的部分可动画属性修改时,就是隐式动画。
- 直接对
UIView
或其CALayer
设置一个可动画的属性值时,会出发系统的隐式动画,可动画的属性值,可以在UIView
或其CALayer
的文档中找到,属性标有Animatable
- 注意:
- 因为主
CALayer
,系统默认关闭了隐式动画,所以当我们直接修改这些可动画属性值时,变化时直接生效的,没有动画效果。 - 如果修改的是一个自建的单独
CALayer
时,帧与帧之间的变化还是会触发系统的默认隐式动画,这个时候就需要我们来手动关闭隐式动画 - 隐式动画所做的事情和显示动画是一样的,我们设置的属性值都是模型层的数值,而系统会自动添加属性对应的
CAAnimation
动画到CALayer
上。 UIView
有一系列的animateWithDuration
动画方法,在这些方法中UIView
会恢复隐式动画,所以在动画的block
中修改属性时,又会触发隐式动画。
- 因为主
iOS动画原理的更多相关文章
- 解析 iOS 动画原理与实现
这篇文章不会教大家如何实现一个具体的动画效果,我会从动画的本质出发,来说说 iOS 动画的原理与实现方式. 什么是动画 动画,顾名思义,就是能“动”的画.人的眼睛对图像有短暂的记忆效应,所以当眼睛看到 ...
- 简析iOS动画原理及实现——Core Animation
本文转载至 http://www.tuicool.com/articles/e2qaYjA 原文 https://tech.imdada.cn/2016/06/21/ios-core-animati ...
- Atitit 视频编码与动画原理attilax总结
Atitit 视频编码与动画原理attilax总结 1.1. 第一步:实现有损图像压缩和解压1 1.2. 接着将其量化,所谓量化,就是信号采样的步长,1 1.3. 第二步:实现宏块误差计算2 1.4. ...
- SVG描边动画原理
SVG描边动画原理其实很简单,主要利用以下两个属性 stroke-dasharray 制作虚线,使得黑白相间, stroke-dashoffset 使得虚线向开头偏移,这里的1500不精确,是我随便取 ...
- JS实现动画原理一(闭包方式)
前提: 你必须了解js的闭包(否则你看不懂滴) 我们就来做一个js实现jq animate的动画效果来简单探索一下,js动画实现的简单原理: html代码 <div id=&q ...
- (转)iOS动画Core Animation
文章转载:http://blog.sina.com.cn/s/blog_7b9d64af0101b8nh.html 在iOS中动画实现技术主要是:Core Animation. Core Animat ...
- IOS动画隐式,显式,翻页
// ViewController.m // IOS动画0817 // // Created by 张艳锋 on 15/8/17. // Copyright (c) 2015年 张艳锋. Al ...
- 【Xamarin挖墙脚系列:Xamarin.IOS机制原理剖析】
原文:[Xamarin挖墙脚系列:Xamarin.IOS机制原理剖析] [注意:]团队里总是有人反映卸载Xamarin,清理不完全.之前写过如何完全卸载清理剩余的文件.今天写了Windows下的批命令 ...
- iOS 动画基础
原文:http://www.cnblogs.com/lujianwenance/p/5733846.html 今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学, ...
随机推荐
- 4.0 spring-注册解析的Bean
1.0 registerBeanDefinition 对于配置文件,解析也解析完了,装饰也装饰完了,对于得到的BeanDefinition已经可以满足后续的使用了,唯一剩下的工作就是注册了, 也就是: ...
- asp.net单点登录(SSO)解决方案
前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助.SSO的解决方案很多,但搜索结果令人大失所 ...
- [转载]MongoDB优化的几点原则
.查询优化 确认你的查询是否充分利用到了索引,用explain命令查看一下查询执行的情况,添加必要的索引,避免扫表操作. .搞清你的热数据大小 可能你的数据集非常大,但是这并不那么重要,重要的是你的热 ...
- 浏览器对象模型(BOM)
BOM结构 用户浏览网页的时候,浏览器会自动创建一些对象,这些对象存放着浏览器窗口的属性和相关信息,也就是大家熟称的BOM.浏览器对象模型是一个层次化的对象集,我们可以通过window对象访问所有对象 ...
- firefly的环境搭建(2013年9月25日最新,win下最详图文)
源地址:http://www.9miao.com/question-15-53785.html 一.安装PythonFirefly是采用Python编写的高性能.分布式游戏服务器框架,所以使用Fire ...
- linux fork函数与vfork函数
一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...
- 【前端学习】【jQuery选择器】
jQuery选择器 jQuery选择器 本文内容引自于单东林<锋利的jQuery>,未经原作者准许,禁止以商业目的转载发布! 选择器是jQuery的根基,在jQuery中,对事件处 ...
- thinkphp 减少文件目录
配置 'TMPL_FILE_DEPR'=>'_' 于是模板文件的格式为如:index_index.html,index_show.html .代替原来的目录结构:/index/index.htm ...
- 如何用DELPHI编程修改外部EXE文件的版本信
右击里面有修改 点开直接修改就可以了吧. DELPHI 里程序的版本信息怎么是灰色的,无法更改 耐心读以下说明,应该能解决你的问题,如果不能解决,请Hi我~ 如何给自己的dll文件添加版本信息呢? 首 ...
- C#基础精华07(委托事件,委托的使用,匿名方法)
1.委托概述 委托是一种数据类型,像类一样(可以声明委托类型变量).方法参数可以是int.string.类类型 void M1(int n){ } √ void M2(string s){ } √ ...