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节点不见了!!于是回忆了一下自己之前的操作过程,大概是因为将自己进入文件夹,将某 ...
随机推荐
- Python系列 - optparse
我们知道sys.argv[] 可以获得命令行参数 同样,optparse 对此提供了更为强大的功能. import optparse class ArgvHandler(object): def __ ...
- Java爬虫原理分析
当我们需要从网络上获取资源的时候,我们一般的做法就是通过浏览器打开某个网站,然后将我们需要的东西下载或者保存下来. 但是,当我们需要大量下载的时候,这个时候通过人工一个个的去点击下载,就显得太没有效率 ...
- day4 liaoxuefeng--调试、线程、正则表达式
一.错误.调试和测试 二.进程和线程 三.正则表达式
- IP地址、子网掩码、网关、DNS服务器
1. IP地址 IP是英文Internet Protocol的缩写,意思是"网络之间互连的协议",也就是为计算机网络相互连接进行通信而设计的协议.在因特网中,它是能使连接到网上的所 ...
- Fashion-MNIST:A MNIST-like fashion product database. Benchmark
Zalando的文章图像的一个数据集包括一个训练集6万个例子和一个10,000个例子的测试集. 每个示例是一个28x28灰度图像,与10个类别的标签相关联. 时尚MNIST旨在作为用于基准机器学习算法 ...
- python2.7练习小例子(一)
1)题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去掉不满足条件的 ...
- Go实现海量日志收集系统(四)
到这一步,我的收集系统就已经完成很大一部分工作,我们重新看一下我们之前画的图: 我们已经完成前面的部分,剩下是要完成后半部分,将kafka中的数据扔到ElasticSearch,并且最终通过kiban ...
- IScroll.js 学习笔记
一.css部分1.transform 旋转div { transform:rotate(7deg); -ms-transform:rotate(7deg); /* IE 9 */ -moz-trans ...
- Java并发之BlockingQueue的使用
Java并发之BlockingQueue的使用 一.简介 前段时间看到有些朋友在网上发了一道面试题,题目的大意就是:有两个线程A,B, A线程每200ms就生成一个[0,100]之间的随机数, B线 ...
- VLAN之间单臂路由通信
实验目的 理解单臂路由的应用场景 掌握路由器子接口的配置方法 掌握子接口封装VLAN的配置方法 理解单臂路由的工作原理 实验原理 单臂路由解决用户需要跨越VLAN实现通信的情况. 原理:通过一台路由器 ...