首页 > 解决方案 > 应用关闭时阻止动画完成

问题描述

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

标签: iosswiftxcodeanimationuiview

解决方案


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

    self.carImage.layer.removeAllAnimations()

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

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

请注意,currentPositionFrame将是 a 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
    }
}

推荐阅读