How to tell the active view controller when applicationDidBecomeActive is called?

谁说胖子不能爱 提交于 2019-12-03 06:59:02

问题


I feel I am missing a trick here...

I just want to call viewDidLoad or viewDidAppear on the current active view controller when applicationDidBecomeActive gets called, so I can reset some animations or whatever, when the app is started up again from the background. Some of my views don't care, but others really need to know.

I am using Storyboards and my app delegate file has the standard functions - but all with EMPTY bodies. For example, didFinishLaunchingWithOptions just returns YES and does nothing else. Storyboard automagically does everything I guess.

So how can I talk to the current view controller from my rather blank, information free, app delegate?


回答1:


I would recommend using notifications.

In your app delegate's applicationdidBecomeActive method put in this code:

[[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];

In your current active view controller's init method subscribe to the notification.

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(updateStuff)        
                                             name:@"appDidBecomeActive" 
                                           object:nil];

Implement the "updateStuff" method in your controller and you should be able to do whatever you want when the app becomes active.




回答2:


Instead of sending a notification from your app delegate, the OS sends a notification automatically that you can observe:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(initSongInfo)
                                             name:UIApplicationDidBecomeActiveNotification
                                           object:nil];

and of course make sure to stop observing sometime before or inside your dealloc method, by calling:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification 
                                              object:nil];



回答3:


Swift version:

You can add this row in your viewDidLoad

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)

func viewDidBecomeActive(){
    print("viewDidBecomeActive")
}

Swift 5.x version

NotificationCenter.default.addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)

@objc func viewDidBecomeActive() {
    print("viewDidBecomeActive")
}



回答4:


Rather than trying to keep track of which ViewController is current, you could send a NSNotification from your AppDelegate and subscribe to it in your ViewController.. That way the view controller keeps track of whether or not it needs to call viewDidAppear.




回答5:


your AppDelegate will have a window property, that window will have a rootViewController property. You can find your viewController here.

If you are using a TabBarController, the rootviewcontroller will be the tabbarcontroller, and you can call the tabbarcontroller's selectedViewController to get the current viewController.

UIViewController *rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
if ([rootViewController isKindOfClass:[UITabBarController Class]])
    rootViewController = ((UITabBarController *)rootViewController).selectedViewController;
else if ([rootViewController isKindOfClass:[UINavigationController Class]])
    rootViewController = ((UINavigationController *)rootViewController).topViewController;

[rootViewController viewDidAppear];

If you have a more complex view hierarchy with navigation controllers, or modal views, you can call on presentedViewController, or topViewController.




回答6:


Ok so it's pretty catastrophic.

You guys have to pay attention to events registration/unregistration cause you can cause memory leaks.

To make everything work you need to set a flag which knows what's the registration status: either you signed to background events or not. Notice that you need to register to the events when the view controller is seen by the user (if he came from a different one) or if he came from the home screen to your view controller.

You also need to unregister when you leave the view controller to a different one.

In short:

Swift 4:

private var registeredToBackgroundEvents = false

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    registerToBackFromBackground()
}

/// register to back from backround event
private func registerToBackFromBackground() {
    if(!registeredToBackgroundEvents) {
        NotificationCenter.default.addObserver(self, 
        selector: #selector(viewDidBecomeActive), 
        name: UIApplication.didBecomeActiveNotification, object: nil)
        registeredToBackgroundEvents = true
    }
}

/// unregister from back from backround event
private func unregisterFromBackFromBackground() {
    if(registeredToBackgroundEvents) {
        NotificationCenter.default.removeObserver(self, 
        name: UIApplication.didBecomeActiveNotification, object: nil)
        registeredToBackgroundEvents = false
    }

}

@objc func viewDidBecomeActive(){
    logicManager.onBackFromStandby()
}


override func viewWillDisappear(_ animated: Bool) {
    unregisterFromBackFromBackground()
}


来源:https://stackoverflow.com/questions/10359186/how-to-tell-the-active-view-controller-when-applicationdidbecomeactive-is-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!