了解 UIView.animate 以及完成闭包的工作原理

Understanding UIView.animate and how completion closures work

有没有一种方法可以中断动画,而不是"cancel"(倒带)它们,而是"fast-forwards"它们强制完成关闭到 运行原计划?

背景:

在 IOS 中,可以 "animate a view with duration" 并包含一个完成闭包...像这样使用 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 [=12=] {
                    UIView.animate(withDuration: 1, animations: {
                        self.bigLabel.center.x -= 20
                    }, completion: {
                        if [=12=] {
                            self.updateMainDisplay()
                        }
                    }) }
            })
        }

所以我们有一个 UILabel,bigLabel,我们首先对 "fade," 进行动画处理,然后我们链接到第一个完成后的另一个动画,然后再次完成第二个,我们 运行 最重要的函数,updateMainDisplay()。

但是这个简单的示例可能会复杂得多,涉及更多的视图。执行 updateMainDisplay() 可能是必要的。 ;)

updateMainDisplay() 函数很重要,因为它 "resets" 所有视图,将应用程序返回到类似于应用程序最初启动时的中性状态......有点 "re-calibrates" 一切。

Anyhoo,问题是,如果用户在动画播放时做了一些事情,比如尽早按下主页按钮或切换到新的 activity(模态,比如设置......然后回来)发生,它永远不会完成... 所以 updateMainDisplay() 不会被执行! ...事情变得复杂和讨厌。

那么,如何处理这个问题呢?

似乎需要在 "onPause()" 中完成一些事情(我知道这不是 Android)...例如确保取消动画并执行 updateMainDisplay()。

但是为了做到这一点,您必须在 "onPause()" 方法中检查各种布尔状态。如果有一种方法可以保证动画完成,我会更愿意。

所以,再一次,我认为如果有一种方法可以不取消动画,而是取消所有动画"force immediate completion",那就太棒了.

这是伪代码...但是有没有办法做这样的事情:

var myAnimation = (animation) { // EXHIBIT-A from above } 

myAnimation.execute()

// if needed:

myAnimation.forceCompletionNow()

有人知道这是否可行吗?

谢谢。

您的代码存在问题,您正在检查完成闭包的第一个参数。这表明动画是否完成。如果那是真的,你只有 运行 updateMainDisplay()

所以事实上,即使动画没有完成,完成处理程序也会被调用。是告诉它如果动画没有结束什么都不做。

要解决此问题,只需删除 if [=12=] 语句即可。

现在 Xcode 将显示警告,因为您没有使用闭包的第一个参数。要消除此警告,只需将 _ in 放在闭包的开头:

{ _ in
    // some code
}

您可以尝试的另一件事是 CABasicAnimation,它 实际上 不会更改视图的属性。它使 CALayer 动画化。如果您以某种方式再次更新视图,视图将回到动画之前的原始状态。您似乎想在动画结束后重置所有内容,所以这可能适合您。