21

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

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

我正在使用 Storyboards,我的应用程序委托文件具有标准功能 - 但都带有 EMPTY 主体。例如,didFinishLaunchingWithOptions 只返回 YES,不执行任何其他操作。Storyboard 会自动完成我猜想的一切。

那么如何从我相当空白、无信息的应用程序委托中与当前视图控制器对话呢?

4

6 回答 6

55

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

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

当然,请确保在您的 dealloc 方法之前或内部的某个时间停止观察,方法是调用:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                      name:UIApplicationDidBecomeActiveNotification 
                                      object:nil];
于 2012-06-12T01:53:45.857 回答
23

我建议使用通知。

在您的应用程序委托的 applicationdidBecomeActive 方法中输入以下代码:

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

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

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

在你的控制器中实现“updateStuff”方法,当应用程序激活时,你应该能够做任何你想做的事情。

于 2012-04-27T23:53:22.060 回答
8

斯威夫特版本:

您可以在 viewDidLoad 中添加此行

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

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

斯威夫特 5.x 版本

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

@objc func viewDidBecomeActive() {
    print("viewDidBecomeActive")
}
于 2016-07-08T13:19:46.787 回答
2

好吧,这是相当灾难性的。

你们必须注意事件注册/注销,因为您可能会导致内存泄漏。

为了使一切正常,您需要设置一个知道注册状态的标志:您是否已登录后台事件。请注意,当用户看到视图控制器(如果他来自其他用户)或者如果他从主屏幕来到您的视图控制器时,您需要注册事件。

当您将视图控制器留给另一个视图控制器时,您还需要取消注册。

简而言之:

斯威夫特 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()
}
于 2019-04-30T00:11:24.503 回答
0

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

于 2012-04-27T23:50:23.647 回答
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];

如果你有一个更复杂的带有导航控制器的视图层次结构,或者模式视图,你可以调用presentedViewController,或者topViewController。

于 2012-04-28T00:04:03.333 回答