设置UIView属性会明确停止/完成现有动画,该动画是在同一属性上使用UIViewPropertyAnimator启动的

时间:2018-10-17 04:12:32

标签: ios swift animation uiviewpropertyanimator

我目前对iOS开发人员的了解程度是,我仍然很陌生,并且处于学习阶段。提供此信息,以便专家可以做出相应的回答:)

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

链接到视频中的确切授课位置https://youtu.be/84ZhYhAwYqo?t=209

也说了同样相当相似的话作为对stackoverflow问题的答案。直接链接回答https://stackoverflow.com/a/3076451/8503233

但是当我尝试这样做时却没有发生。

为了对此进行测试,我制作了一个简单的应用程序,其中单击按钮开始使用UIViewPropertyAnimator.runningPropertyAnimator对视图进行动画处理,并将其alpha更改为0。持续时间设置为10秒,因此我有足够的时间来触发另一个动画。

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

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

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

EDIT1:

查看控制器代码

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的评论中,所显示的是动画现在是可加的。这澄清了很多事情,但是苹果公​​司的 addAnimations(_:delayFactor:)文档说了,我引用了

  

如果动画块修改了由其他属性动画师修改的属性,则动画师将以最合适的方式合并其更改。对于许多属性,来自每个动画师的更改将加在一起以产生新的中间值。如果无法以这种加法方式修改属性,则新动画将接管,就像为基于视图的动画指定了beginFromCurrentState选项一样。

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

1 个答案:

答案 0 :(得分:0)

您正在查阅古代历史(您引用的答案来自2010年!)。 使用的确是这样,对于视图动画,在已被动画处理的视图属性上订购动画会突然取消现有的动画。但是在最新版本的iOS中,视图动画是 additive ,这意味着默认情况下,新动画将与现有的飞行中动画平​​滑组合。