Home > OS >  How do I continue animating after the app is alive?
How do I continue animating after the app is alive?

Time:11-17

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.

Refer the enter image description here

  • Related