应用关闭时阻止动画完成

Prevent animation from completion when app closes

我得到了一个动画,一辆汽车开到屏幕中间。到达后,汽车停在那里直到我回到这个视图,然后汽车再次开回。但是当我在汽车位于屏幕中间时关闭应用程序并关闭并重新打开应用程序时,汽车隐藏在起始位置而不是屏幕中间。我认为动画已经完成并且 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 放在一个视图中,它在所有设备上的大小都相同,所以它工作得很好。

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

    self.carImage.layer.removeAllAnimations()

如果单独这样做不起作用,那么您还可以在停止动画之前存储视图的位置,并在应用程序处于后台时保留它们:

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

请注意,currentPositionFrame 将是 CGRect?,因此您必须处理可选项,但这应该是合理的,因为您可能有也可能没有 carImage 无论如何打开屏幕。

更新:

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

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
    }
}