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

问题描述 投票:18回答:6

我觉得我在这里错过了一招

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

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

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

ios iphone swift xcode-storyboard
6个回答
21
投票

我建议使用通知。

在您的app代理的applicationDidBecomeActive方法中放入此代码:

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

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

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

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


55
投票

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

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

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

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

3
投票

Swift版本:

您可以在viewDidLoad中添加此行

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

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

0
投票

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


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。


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()
}
© www.soinside.com 2019 - 2024. All rights reserved.