将显式设置 UIView 属性 stop/finish 现有动画,该动画是在同一个 属性 上使用 UIViewPropertyAnimator 启动的

Would setting a UIView property explicitly stop/finish an existing animation which was started using UIViewPropertyAnimator on the same property

我目前的 iOS 开发知识水平是我对它还很陌生,处于学习阶段。提供此信息以便专家可以相应地回答:)

根据斯坦福大学的 iOS 开发课程,据说如果另一个动画针对相同的 属性 开始,则 UIView 属性 的动画将被中断(更具体地说新动画开始处理前一个动画的属性之一)。

Link 到视频中讲授此内容的确切位置 https://youtu.be/84ZhYhAwYqo?t=209

在 Whosebug 上的一个问题的回答中也提到了同样相当相似的话。直接link回答

但是当我尝试这样做时,它并没有发生。

为了测试这一点,我制作了一个简单的应用程序,其中单击按钮开始使用 UIViewPropertyAnimator.runningPropertyAnimator 为视图设置动画,其中它将 alpha 更改为 0。持续时间设置为 10 秒,以便我有足够的时间触发另一个动画。

然后另一个按钮将启动一个动画,将同一视图的 alpha 更改为 1。我预计当第二个动画开始时,它会导致第一个动画停止并使用值调用其完成处理程序UIViewAnimatingPosition 为 .current.

但我发现,即使第二个动画开始时,第一个动画仍然是 运行,并且在 运行 的整个持续时间之后,完成处理程序以 UIViewAnimatingPosition 作为 .end 调用。

这与我在上面提供的资源中读到的完全相反。请帮忙。这里究竟发生了什么。如果需要,将共享应用程序代码。谢谢!!!

编辑 1:

查看控制器代码

class MyViewController: UIViewController {

    @IBOutlet weak var viewToAnimate: UIView!
    @IBOutlet weak var statusView: UIView!

    @IBAction func buttonAnimate1(_ sender: UIButton) {
        UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 5, delay: 0, options: [], animations: {
            self.viewToAnimate.alpha = 0.1
        }, completion: {position in
            switch position {
            case .start:
                print("In animation 1 completion block with position = start")
            case .current:
                print("In animation 1 completion block with position = current")
            case .end:
                print("In animation 1 completion block with position = end")
            }
            self.statusView.backgroundColor = UIColor.brown
        })
    }


    @IBAction func buttonAnimate2(_ sender: UIButton) {
        UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 5, delay: 0, options: [.beginFromCurrentState], animations: {
            self.viewToAnimate.alpha = 1
        }, completion: {position in
            switch position {
            case .start:
                print("In animation 2 completion block with position = start")
            case .current:
                print("In animation 2 completion block with position = current")
            case .end:
                print("In animation 2 completion block with position = end")
            }
            self.statusView.backgroundColor = UIColor.green
        })
    }


    @IBAction func buttonRestore(_ sender: UIButton) {
        viewToAnimate.alpha = 1
        statusView.backgroundColor = UIColor.yellow
    }
}

测试步骤:

在模拟器中,我按下 Animate1 按钮,大约 1 秒后,我按下 Animate2 按钮。

控制台输出:

In animation 1 completion block with position = end
In animation 2 completion block with position = end

在@matt 的评论中,所说的是动画现在是附加的。这澄清了很多事情,但 Apple 的 addAnimations(_:delayFactor:) 文档说,我引用

If the animation block modifies a property that is being modified by a different property animator, then the animators combine their changes in the most appropriate way. For many properties, the changes from each animator are added together to yield a new intermediate value. If a property cannot be modified in this additive manner, the new animations take over as if the beginFromCurrentState option had been specified for a view-based animation.

因此,如果新动画以隐式或显式方式接管 beginFromCurrentState,那么当新动画接管时,第一个动画不应该以 .current 状态停止吗?

您正在查阅古代历史(您引用的答案是 2010 年的!)。 过去确实是这样,在使用视图动画时,在视图 属性 已经设置动画的视图上订购动画会突然取消现有动画。但在 iOS 的最新版本中,视图动画已 加法 ,这意味着默认情况下,新动画将与现有的飞行动画平滑结合。