第三方开源动画库EasyAnimation中一个小bug的修复
2016-06-14 10:31
447 查看
看过iOS动画之旅的都知道,其中在最后提到一个作者写的开源动画库EasyAnimation(以下简称EA).
EA对CoreAnimation中的view和layer动画做了更高层次的包装和抽象,使得我们可以大大减少编写代码的行数.
不过在玩耍EA时发现了点小问题,在使用链式串行调用中其中的某一段若为弹簧动画,则该动画后面的其他动画都无法再运行了.
以下是测试代码:
以上我们总共串行执行了3段动画,上面数字注释分别依次指明当前的动画段.
在第一段中我们旋转按钮,在第二段动画中我们修改按钮的边角,边线的样式,在最后一段中我们恢复第二段中做的样式修改.
注意第二段中我们使用了弹簧动画,执行App你会发现第三段动画无法被触发!
cmd+鼠标左键点击第二段中的弹簧动画,我们看一下EA源代码:
其中返回了另一个EAAnimationDelayed对象,我们再看一下animateAndChainWithDuration这个方法:
如你所见,该方法只是简单的把CoreAnimation动画中的一些参数放到EAAnimationDelayed对象中来,同时很重要的一步是在方法最后建立EAAnimationDelayed执行链.
我们最后看一下执行链是如何执行的,看一下run方法:
注意,其中根据springDaming属性的值决定调用何种动画方法!但是在前面EA的animateWithDuration方法中我们赋值的是self的属性,而不是anim的属性!
将EA源代码中上面两句赋值语句修改如下:
再次运行,可以看到恢复动画可以正常运行了:]
EA对CoreAnimation中的view和layer动画做了更高层次的包装和抽象,使得我们可以大大减少编写代码的行数.
不过在玩耍EA时发现了点小问题,在使用链式串行调用中其中的某一段若为弹簧动画,则该动画后面的其他动画都无法再运行了.
以下是测试代码:
@IBAction func actionAddItem(sender: AnyObject) { plusButton.enabled = false UIView.animateAndChainWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.33, initialSpringVelocity: 0.0, options: [], animations: { //1 self.plusButton.transform = CGAffineTransformRotate(self.plusButton.transform, CGFloat(-M_PI_2)) }, completion: {_ in self.addRandomItem() }).animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.33, initialSpringVelocity: 0.0, options: [], animations: { //2 self.plusButton.layer.cornerRadius = 62.5 self.plusButton.layer.borderWidth = 2.0 self.plusButton.layer.borderColor = UIColor.grayColor().CGColor }, completion: nil).animateWithDuration(0.15, delay: 0.5, options: [.CurveEaseOut,/*.Repeat*/], animations: { //3 self.plusButton.layer.cornerRadius = 0.0 self.plusButton.layer.borderWidth = 0.0 self.plusButton.layer.borderColor = UIColor.clearColor().CGColor }, completion: {_ in self.plusButton.enabled = true }) }
以上我们总共串行执行了3段动画,上面数字注释分别依次指明当前的动画段.
在第一段中我们旋转按钮,在第二段动画中我们修改按钮的边角,边线的样式,在最后一段中我们恢复第二段中做的样式修改.
注意第二段中我们使用了弹簧动画,执行App你会发现第三段动画无法被触发!
cmd+鼠标左键点击第二段中的弹簧动画,我们看一下EA源代码:
public func animateWithDuration(duration: NSTimeInterval, delay: NSTimeInterval, usingSpringWithDamping dampingRatio: CGFloat, initialSpringVelocity velocity: CGFloat, options: UIViewAnimationOptions, animations: () -> Void, completion: ((Bool) -> Void)?) -> EAAnimationDelayed { let anim = animateAndChainWithDuration(duration, delay: delay, options: options, animations: animations, completion: completion) self.springDamping = dampingRatio self.springVelocity = velocity return anim }
其中返回了另一个EAAnimationDelayed对象,我们再看一下animateAndChainWithDuration这个方法:
public func animateAndChainWithDuration(duration: NSTimeInterval, delay: NSTimeInterval, options: UIViewAnimationOptions, animations: () -> Void, completion: ((Bool) -> Void)?) -> EAAnimationDelayed { var options = options if options.contains(.Repeat) { options.remove(.Repeat) loopsChain = true } self.duration = duration self.delay = delay self.options = options self.animations = animations self.completion = completion nextDelayedAnimation = EAAnimationDelayed() nextDelayedAnimation!.prevDelayedAnimation = self return nextDelayedAnimation! }
如你所见,该方法只是简单的把CoreAnimation动画中的一些参数放到EAAnimationDelayed对象中来,同时很重要的一步是在方法最后建立EAAnimationDelayed执行链.
我们最后看一下执行链是如何执行的,看一下run方法:
func run() { if debug { print("run animation #\(debugNumber)") } //TODO: Check if layer-only animations fire a proper completion block if let animations = animations { options.insert(.BeginFromCurrentState) let animationDelay = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * self.delay )) dispatch_after(animationDelay, dispatch_get_main_queue()) { if self.springDamping > 0.0 { //spring animation UIView.animateWithDuration(self.duration, delay: 0, usingSpringWithDamping: self.springDamping, initialSpringVelocity: self.springVelocity, options: self.options, animations: animations, completion: self.animationCompleted) } else { //basic animation UIView.animateWithDuration(self.duration, delay: 0, options: self.options, animations: animations, completion: self.animationCompleted) } } } }
注意,其中根据springDaming属性的值决定调用何种动画方法!但是在前面EA的animateWithDuration方法中我们赋值的是self的属性,而不是anim的属性!
将EA源代码中上面两句赋值语句修改如下:
anim.springDamping = dampingRatio anim.springVelocity = velocity
再次运行,可以看到恢复动画可以正常运行了:]
相关文章推荐
- CRC(16位)多项式为 X16+X15+X2+1
- 队列的应用
- 深入理解DIV和SPAN的区别
- Java那点事――StringBuffer与StringBuilder原理与区别
- HTML之CSS段落样式
- 2016.6.14 hadoop新手入门视频
- 天气预报模块的实现分析
- LinuxSvn服务器搭建之代码同步web目录
- 不同服务器上的Java项目文件同步 解决方案(socket 、http)
- nodejs调用c++程序测试代码
- PowerShell下载文件
- 自定义HBase的协处理器(Observer)
- SparseBooleanArray sba
- 为自己的AndroidStudio添加Material Design Icons ADT Template
- iOS UIAlterController
- 物联网和ERP的未来
- iOS围绕某点缩放或旋转的AnchorPoint的设定
- 线性回归 Linear Regression
- 【Knockout.js 学习体验之旅】(3)模板绑定
- listview调用notifyDataSetChanged()后不刷新界面