CoreAnimation中layer动画闪烁的原因及解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)
网上有一段Core Animation层动画的例子,是将view中的云朵从左向右移动,直到移出屏幕,这时再将云朵移到最左端然后重复移动动画.
所有动画在layer上完成,不过有个小问题,就是第一次每朵云动画完成时,会在其原位置处有一个闪烁,然后才会移动到屏幕最右端,而随后的运动动画都没有这个问题了:
由于录制gif文件时使用的帧率比较低,所以上图较难展示这个问题.不过实际App运行的时候每朵云在第一次移出屏幕的时候都会在初始位置闪烁一下再运行随后的动画.这是为什么呢?
因为layer动画不同于view层面上的动画,它实际不会修改原始view的任何属性.就拿云朵移动的动画来说,你虽然看上去改变了云朵的x坐标使其向右移动,可实际上原来的云朵ImageView根本还在原地,只不过CA用其外观创建了一个临时绘制进行移动,原来的云朵被暂时隐藏起来;一旦移动动画完成,该临时对象被删除,原来的云朵会在初始位置出现.
那么为什么只有动画第一次会出现闪烁呢?因为在第一次动画结束后,我在代码中修改了云朵view的x坐标,所以后面云朵的x坐标都和layer动画的fromValue相同,这将保证后续动画不会发生”闪烁”
知道了原因,解决就很简单了,我只要在第一次动画前将云朵的x坐标修改为指定的位置,同时调整fromValue的值为初始位置即可:
func animateCloud(layer:CALayer){
let cloudSpeed = 15.0/Double(view.layer.frame.size.width)
let duration:NSTimeInterval = Double(view.layer.frame.size.width - layer.frame.origin.x) * cloudSpeed
//提前存储云朵layer的初始位置
let fromValue = layer.position
//设置云朵的最终位置
layer.position.x = -layer.bounds.width/2
let cloudMove = CABasicAnimation(keyPath: "position.x")
cloudMove.fillMode = kCAFillModeForwards
//cloudMove.removedOnCompletion = false
cloudMove.duration = duration
//设置云朵的初始位置
cloudMove.fromValue = fromValue.x
cloudMove.toValue = self.view.bounds.size.width + layer.bounds.width/2
cloudMove.delegate = self
cloudMove.setValue("cloud", forKey: "name")
cloudMove.setValue(layer, forKey: "layer")
layer.addAnimation(cloudMove, forKey: nil)
}
CoreAnimation中layer动画闪烁的原因及解决的更多相关文章
- ios中layer动画和UIView动画代码总结
kCATransitionFade淡出 kCATransitionMoveIn覆盖原图 kCATransitionPush推出 kCATransitionReveal底部显出来 pageC ...
- bootstrap4中bootstrap_treeview不显示图标原因以及解决办法
1.bootstrap4中bootstrap_treeview不显示图标原因 查看过大神的博客,经过自己试验,插件依赖: bootstrap/3.3.7 jquery/3.3.1 <link h ...
- 用adb pull命令从android系统中读取文件失败的原因及解决办法
问题:使用adb pull命令从android系统中读取文件失败.显示:Permission denied 原因:是由于文件权限原因引起. 使用ls -l命令查看android系统中的 ...
- ionic build android 中的报错详细原因以及解决方法
一.执行打包命令 ionic build android 1.报错: 原因: 其实也并非报错,但是会一直在下载gradle,由于网络或者其他原因,导致下载比较慢, 解决方案: 手动下载gradle,并 ...
- VUE 2.0在IE中打开页面空白的原因及解决方法
前言 因为工作的需要,学习Vue2.0也有一段时间,最近在用Vue2.0的官方脚手架工具构建的项目,chrome中跑一直没有问题,但ie打开出现了bug: 问题 ie打开vue2.0项目空白,控制台报 ...
- java中多线程产生死锁的原因以及解决意见
1. java中导致死锁的原因 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结 ...
- IIS7中Ajax.AjaxMethod无效的原因及解决方法
使用Ajax.AjaxMethod方法在asp.net的服务器下一切正常,用iis的时候,js中总是cs类找不到,具体的解决方法如下,遇到类似情况的朋友可以参考下 最近做用Ajax.AjaxMetho ...
- 搞懂js中小数运算精度问题原因及解决办法
js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言中的double类型(双精度浮点型),不区分浮点型和整数型. number类 ...
- hadoop中DataNode消失挂掉的原因及解决方法
昨天在进行Hadoop实验时遇到一个问题,在sbin目录下输入jps命令,查看当前节点的状态时,意外发现DataNode节点不见了!!于是回忆了一下自己之前的操作过程,大概是因为将自己进入文件夹,将某 ...
随机推荐
- 医疗器械c#上位机开发指引教程
此教程面向的读者:对医疗器械上位机编程有兴趣,或者急需了解医疗器械(尿常规.血液分析.生化.心电.B超等医疗下位仪器)的编程流程.编程细节的程序员. 1.得到仪器协议 当我们需要与医疗器械等下位机数据 ...
- ●BZOJ 4176 Lucas的数论
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4176 题解: 莫比乌斯反演,杜教筛 首先有这么一个结论: 令d(n)表示n的约数的个数(就是 ...
- 洛谷mNOIP模拟赛Day1-分组
传送门 首先是贪心的思路 从后向前选,能多选就多选, 理由:数字越少肯定越优,同时间隔尽量向前推,字典序尽量小 对于K==1,枚举1~512直接判断 对于K==2,需要用镜像并查集,来刻画" ...
- 2015 多校联赛 ——HDU5389(dp)
Sample Input 4 3 9 1 1 2 6 3 9 1 2 3 3 5 2 3 1 1 1 1 1 9 9 9 1 2 3 4 5 6 7 8 9 Sample Output 1 0 1 ...
- Windows、Unix、Linux是什么类型的操作系统?
Windows:具有图形用户界面的视窗操作系统. Unix:多用户分时操作系统. Linux:类似Unix操作系统,用于个人计算机.
- JavaBean实现用户登陆
本文简单讲述使用javabean实现用户登录,包括用户登录,注册和退出等. 系统结构图 2.数据库表 create table P_USER ( id VARCHAR2(50) not n ...
- VC++6.0连接MySQL数据库(MySQL API)
一.MySQL的安装 Mysql的安装去官网下载就可以...最新的是5.7版本..二.VC6.0的设置(1)打开VC6.中选0 工具栏Tools菜单下的Options选项,在Directories ...
- h5的input的required使用中遇到的问题
form提交时隐藏input发生的错误 问题描述 在form表单提交的时候,有些input标签被隐藏,表单验证过程中会出现An invalid form control with name='' is ...
- C#之Action和Func的用法
以前我都是通过定义一个delegate来写委托的,但是最近看一些外国人写的源码都是用action和func方式来写,当时感觉对这很陌生所以看起源码也觉得陌生,所以我就花费时间来学习下这两种方式,然后发 ...
- git遇到的问题
push代码时出现的问题: ! [remote rejected] HEAD -> (unpacker error)) 解决办法: $ git push --no-thin origin rel ...