如何在调用applicationDidBecomeActive时告诉活动视图控制器?

时间:2012-04-27 23:36:45

标签: ios iphone swift xcode-storyboard

我觉得我在这里错过了一个技巧......

我只想在调用applicationDidBecomeActive时调用当前活动视图控制器上的viewDidLoad或viewDidAppear,这样当我再次从后台启动应用程序时,我可以重置一些动画或其他任何动画。我的一些观点并不关心,但其他人真的需要知道。

我正在使用Storyboards,我的app委托文件具有标准功能 - 但都使用EMPTY主体。例如,didFinishLaunchingWithOptions只返回YES而不执行任何操作。故事板自动完成我猜的所有事情。

那么如何从我相当空白,无信息的应用代表那里与当前的视图控制器交谈?

6 个答案:

答案 0 :(得分:55)

操作系统不会从您的应用代理发送通知,而是自动发送通知,您可以观察:

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

当然要确保在dealloc方法之前或之内的某个时间停止观察,通过调用:

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

答案 1 :(得分:21)

我建议使用通知。

在你的app代理中,applicationdidBecomeActive方法放在这段代码中:

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

在您当前的活动视图控制器的init方法中订阅通知。

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

在您的控制器中实施“updateStuff”方法,您应该能够在应用程序变为活动状态时执行任何操作。

答案 2 :(得分:3)

Swift版本:

您可以在viewDidLoad

中添加此行
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)

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

答案 3 :(得分:0)

您可以从AppDelegate发送NSNotification并在ViewController中订阅它,而不是试图跟踪哪个ViewController是最新的。这样,视图控制器就会跟踪它是否需要调用viewDidAppear。 / p>

答案 4 :(得分:0)

你的AppDelegate将有一个window属性,该窗口将具有rootViewController属性。你可以在这里找到你的viewController。

如果您使用的是TabBarController,则rootviewcontroller将是tabbarcontroller,您可以调用tabbarcontroller的selectedViewController来获取当前的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];

如果你有一个更复杂的视图层次结构,包含导航控制器或模态视图,你可以调用presentViewController或topViewController。

答案 5 :(得分:0)

好,这是灾难性的。

你们必须注意事件的注册/取消注册,因为这可能导致内存泄漏。

要使所有功能正常工作,您需要设置一个标志,该标志知道什么是注册状态:您是否签署了后台事件。请注意,当用户看到视图控制器时(如果他来自另一个用户),或者如果他从主屏幕来到视图控制器,则需要注册事件。

将视图控制器留给其他控制器时,您还需要注销。

简而言之:

快捷键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()
}