I am using this code to create a rotating animation in my application:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver( self, selector: #selector(ViewController.applicationDidBecomeActive(notification:)),
name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
NotificationCenter.default.addObserver( self, selector: #selector(ViewController.applicationDidEnterBackground(notification:)), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
animationStatus(true)
}
func animationStatus(_ enable: Bool) {
if enable {
if vinylStatus == "true" {
resumeLayer(layer: vinylView.layer)
} else {
rotateImageView()
resumeLayer(layer: vinylView.layer)
}
} else {
pauseLayer(layer: vinylView.layer)
}
}
func rotateImageView() {
vinylStatus = "true"
UIView.animate(withDuration: 3, delay: 0, options: .curveLinear, animations: {
self.vinylView.transform = self.vinylView.transform.rotated(by: .pi / 2)
}) { (finished) in
if finished {
self.rotateImageView()
}
}
}
func pauseLayer(layer: CALayer) {
let pausedTime: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
}
func resumeLayer(layer: CALayer) {
let pausedTime: CFTimeInterval = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
layer.beginTime = timeSincePause
}
But I want to continue animating after the application has been hidden and reopened and I use this code but animations stops and it doesn't work. How to fix this issue?
@objc func applicationDidBecomeActive(notification: NSNotification) {
print("applicationDidBecomeActive")
}
@objc func applicationDidEnterBackground(notification: NSNotification) {
//pauseLayer(layer: vinylView.layer)
}
}
Update
I don't understand. For example in applicationDidBecomeActive
I have only this code: print("applicationDidBecomeActive")
. And if I open control center or notification center and return to app in debug I get this applicationDidBecomeActive
but my animation doesn't stop. But if I hide app and return or lock iPhone and return to app I get this in debug too applicationDidBecomeActive
but in this case animation stopes. Why this happens?
CodePudding user response:
Just call the animating function again
@objc func applicationDidBecomeActive(notification: NSNotification) {
animationStatus(true)
}
@objc func applicationDidEnterBackground(notification: NSNotification) {
animationStatus(false)
}
}
CodePudding user response:
TLDR;
You do not need a complicated start-pause-resume-stop code to continue animation when app comes to foreground.
You do not need to observe
the applicationDidBecomeActive
and applicationDidEnterBackground
events either.
Instead, observe applicationWillEnterForeground
event, and call rotateImageView
function from viewDidLoad
(to initially start the animation), and in applicationWillEnterForeground
callback to re-start it when returning from background mode.
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver( self, selector: #selector(AnimationContinuationViewController.applicationWillEnterForeground(notification:)), name:UIApplication.willEnterForegroundNotification, object: nil)
self.rotateImageView()
}
@objc func applicationWillEnterForeground(notification: NSNotification) {
print("applicationWillEnterForeground")
self.rotateImageView()
}
This will fix the animation and also continue the animation from where it was stopped (while going to background).
So now, you can also remove vinylStatus
, animationStatus
, pauseLayer
, resumeLayer
, and other state handling functions unless they serve a different purpose.
More details:
When you open control center (or notification center), the app is only becoming inactive
, and becomes active
when the overlay (control center or notification center) is dismissed.
When the phone is locked, or you go to home screen, the app actually goes to background.
iOS apps do not execute any UI code when in background, so you need to re-start the animation when you come back from background mode.