UIViewPropertyAnimator and application lifecycle

I'm trying to use UIViewPropertyAnimator to animate a progress bar. The progress bar displays the playback time of an audio file.

Approach


0) Given a progress bar and a playback duration

Code Block
let progressBar: UIViewSubclass = ProgressBar(...)
let duration: TimeInterval = ...


1) Create an animator from start to finish on the progress bar:

Code Block
let animator = UIViewPropertyAnimator(duration: duration, curve: .linear)
animator.pausesOnCompletion = true
progressBar.setProgress(0)
animator.addAnimations { [weak self] in
guard let self = self else { return }
self.setProgress(1)
}
animator.pauseAnimation()


2) When a file is played, start it with:

Code Block
let startTime: TimeInterval = ...
animator.fractionComplete = startTime / duration
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)


This works well. It is CPU efficient, and, with a bit of extra code, supports more things, such as dragging the progress bar to a different playback position.

Problem: App/View Lifecycle

Unfortunately, this approach breaks when sending the app into the background and reopening it. After that, animator.continueAnimation() doesn't work anymore, and the animation is stuck at the finish state.

Here is an example project that reproduces this problem: https://github.com/JanNash/AnimationTest/tree/apple-developer-forum-660767
The main logic is in the ViewController:
https://github.com/JanNash/AnimationTest/blob/apple-developer-forum-660767/AnimationTest/ViewController.swift

In this project, a simple progress bar is animated after a button press, and the button press restarts the animation from the beginning. After the app was sent to the background and restored to the foreground, the animation doesn't work anymore.

Question

How do I fix this problem? Is there maybe something inherent to animations that I didn't understand? I could, for example, imagine that the render server loses the animation when the app goes into background, and that as such, animations always have to be recreated when the app - or even a view - enters the foreground. But it would be good to know whether this just requires a simple code change to fix, or whether I have misunderstood something conceptually.

When a UIView (and its underlying CALayer) are removed from the view hierarchy, or are in a UIWindowScene whose activateState changes to .background, any animations on those views are removed. Since this progress view needs to maintain a persistent animation, it should restart that animation when the view receives didMoveToWindow(). didMoveToWindow() would also be a good time to grab the window's windowScene and register for UIScene.didActivateNotification, and restart the animation upon receiving this notification as well.

Thank you for your reply. I did implement it as suggested, and for the most part it works great.

However, I believe I found a problem and potential bug when a UIViewPropertyAnimator is configured in didMoveToWindow in a view that is being presented in a popover. This bug can be reproduced in the following example code:

https://github.com/tcwalther/PropertyAnimatorPresent/tree/29812e53a8b6d413a156d26de3fe3c01792df9a9

In this code, there are two view controllers. The first one contains a button that presents the second view controller as a popover. The second view controller contains one view of type AnimatedView.

The AnimatedView has a UIViewPropertyAnimator that is being configured on didMoveToWindow. When that configuration is called, the property animation works fine, but the popover presentation animation is broken. Have a look at the following screenshots:

Can you advise me how to fix the popover animation?

UIViewPropertyAnimator and application lifecycle
 
 
Q