【问题标题】:Prevent animation from completion when app closes应用关闭时阻止动画完成
【发布时间】:2020-07-27 10:30:07
【问题描述】:

我有一个动画,其中一辆汽车开到屏幕中间。到达时,汽车停在那里,直到我回到这个视图,然后汽车再次开进。但是当我在汽车位于屏幕中间时关闭应用程序并关闭并重新打开应用程序时,汽车隐藏在起始位置而不是屏幕中间。我认为动画完成并且 carImage 进入了起始位置。我怎样才能防止这种情况?我的猜测是,当应用程序关闭时,我必须以某种方式提醒汽车图像的位置,并在应用程序重新打开时将汽车放回该位置,但前提是汽车在应用程序关闭之前就在那里(否则动画将开始在屏幕中间,这会很糟糕..)。

我将向您展示一个快速的屏幕录像以便更好地理解: https://vimeo.com/407626947

我在 ViewDidAppear 中得到了这个:

 UIView.animate(withDuration: 4, animations: {
                   self.carImage.frame.origin.y += 139
                   self.carImage.frame.origin.x += 240
               }, completion: {(finished:Bool) in self.show()})

其中“carImage”是一个带有 car.png 的 UIImageView。我已经手动将它的位置放在左侧某处的 main.storyboard 中,这样就可以了。

我知道,使用 += 139 等对其进行动画处理一点也不好,但是因为我将 carImage 放在了一个视图中,它在所有设备上都是相同的大小,所以它可以完美地工作。

【问题讨论】:

    标签: ios swift xcode animation uiview


    【解决方案1】:

    您可以通过从视图层移除所有动画来停止 UIView 块动画的动画:

        self.carImage.layer.removeAllAnimations()
    

    如果仅此一项不起作用,那么您还可以在停止动画之前存储视图的位置,并在应用程序处于后台时保持它们:

        let currentPositionFrame = self.carImage.layer.presentation()?.frame
        self.carImage.layer.removeAllAnimations()
    

    请注意,currentPositionFrame 将是 CGRect?,因此您必须处理选项,但这应该是合理的,因为当您打开反正屏幕。

    更新:

    为了在背景中保持汽车图像的状态,我将在视图控制器中概述它的主要部分:

    class MyViewController: UIViewController {
        private var oldCarPosition: CGRect? = nil  // here we'll store the position when the app goes to background
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Other setup code
    
            NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterBackground(_:)), name: UIApplication.willResignActiveNotification, object: nil)
    
            NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
        }
    
        deinit {
            // Don't forget to unsubscribe from notifications!
            NotificationCenter.default.removeObserver(self)
        }
    
    
        @objc func applicationWillEnterBackground(_ notification: Notification) {
            self.oldCarPosition = self.carImage.layer.presentation()?.frame
        }
    
        @objc func applicationWillEnterForeground(_ notification: Notification) {
            guard let oldPosition = self.oldCarPosition else { return }
            self.carImage.frame = oldPosition
        }
    }
    

    【讨论】:

    • 谢谢,但我不知道如何使用它。我在制作动画后尝试添加 revomeAllAnimations(),但是当我启动应用程序时,汽车已经位于屏幕中间。如果我在动画之前添加它,它就像以前一样。我应该把所有的 let currentPositionFrame.. 放在哪里,我该如何处理呢?
    • let currentPosition sn-p 应该添加到应用程序进入后台时调用的函数中。实际上,您可能不需要removeAllAnimations() 部分,而只使用汽车的旧位置。如果您需要,我可以编辑我的答案,向您展示如何在应用程序进入后台时执行该代码。
    • 是的,那就太好了!非常感谢弗拉德
    • 很高兴我能帮上忙! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多