是否有办法以不“取消”(倒带)它们的方式中断动画,而是“快进”它们迫使它们的完成闭包比原计划更早地运行?
背景:
在IOS中,可以“为持续时间的视图设置动画”并包含完成闭包...使用UIView的静态方法animate(),如下所示:
class func animate(withDuration: TimeInterval, animations: () -> Void, completion: ((Bool) -> Void)? = nil)
现实生活中的示例可能如下所示 EXHIBIT-A :
// assume we have a UILabel named 'bigLabel'
func animationWeNeedToDo() {
UIView.animate(withDuration: 1, animations: {
self.bigLabel.alpha = 0
}, completion: {
if $0 {
UIView.animate(withDuration: 1, animations: {
self.bigLabel.center.x -= 20
}, completion: {
if $0 {
self.updateMainDisplay()
}
}) }
})
}
所以我们有一个UILabel, bigLabel ,我们首先动画为“淡出”,然后我们在第一个完成之前链接到另一个动画,然后又在完成第二,我们运行所有重要的函数updateMainDisplay()。
但是这个简单的例子可能会更复杂,涉及更多的观点。 updateMainDisplay()执行可能是必要的。 ;)
updateMainDisplay()函数非常重要,因为它会“重置”所有视图,将应用程序恢复到与应用程序最初启动时类似的中性状态......有点“重新校准”所有内容。
Anyhoo,麻烦的是,如果用户做了类似的事情,比如早点按下主页按钮或者进行新的活动(模态,如设置......然后回来),则在动画发生时,它永远不会完成... 所以updateMainDisplay()没有被执行! ......事情变得复杂和讨厌。
那么,如何处理这个问题?
似乎需要在“onPause()”中完成某些事情(我知道这不是Android)...就像确保取消动画并执行updateMainDisplay()一样。
但是为了做到这一点,你必须在“onPause()”方法中检查所有类型的布尔状态。如果有办法保证动画完成,我更喜欢。
所以,再一次,我认为如果有一种方法不取消动画,而是“强制立即完成”所有动画,那将是非常棒的。
这是伪代码......但是有办法做这样的事情:
var myAnimation = (animation) { // EXHIBIT-A from above }
myAnimation.execute()
// if needed:
myAnimation.forceCompletionNow()
有人知道这是否可能?
感谢。
答案 0 :(得分:1)
您的代码存在的问题是您正在检查完成闭包的第一个参数。这表明动画是否结束。如果确实如此,您只运行updateMainDisplay()
。
事实上,即使动画没有完成,也会调用完成处理程序 。 你告诉它如果动画没有完成就什么都不做。
要解决此问题,请删除if $0
声明。
现在Xcode会显示一个警告,因为你没有使用闭包的第一个参数。要使这个警告保持沉默,只需将_ in
放在关闭的开头:
{ _ in
// some code
}
您可以尝试的另一件事是CABasicAnimation
,它不会实际更改视图的属性。它使CALayer
s动画化。如果以某种方式再次更新视图,视图将在动画之前返回其原始状态。您似乎想在动画结束后重置所有内容,因此这可能适合您。