我觉得我在这里错过了一招
我只想在调用applicationDidBecomeActive时调用当前活动视图控制器上的viewDidLoad或viewDidAppear,这样当我再次从后台启动应用程序时,我可以重置一些动画或其他任何动画。我的一些观点并不关心,但其他人真的需要知道。
我正在使用Storyboards,我的app委托文件具有标准功能 - 但所有都使用EMPTY主体。例如,didFinishLaunchingWithOptions只返回YES而不执行任何操作。故事板自动完成我猜的一切。
那么如何从我相当空白,无信息的应用代表那里与当前的视图控制器进行通信?
我建议使用通知。
在您的app代理的applicationDidBecomeActive方法中放入此代码:
[[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];
在当前的活动视图控制器的init方法中订阅通知。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateStuff)
name:@"appDidBecomeActive"
object:nil];
在您的控制器中实现“updateStuff”方法,您应该能够在应用程序变为活动状态时执行任何操作。
操作系统不会从您的应用代理发送通知,而是自动发送通知,您可以观察到:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initSongInfo)
name:UIApplicationDidBecomeActiveNotification
object:nil];
当然,请确保在dealloc方法之前或之内的某个时间停止观察,方法是:
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
Swift版本:
您可以在viewDidLoad中添加此行
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)
func viewDidBecomeActive(){
print("viewDidBecomeActive")
}
您可以从AppDelegate发送NSNotification并在ViewController中订阅它,而不是试图跟踪哪个ViewController是最新的。这样,视图控制器就会跟踪它是否需要调用viewDidAppear。
你的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。
好吧,这是非常灾难性的。
你们必须注意事件注册/取消注册,因为你可能导致内存泄漏。
要使一切正常,您需要设置一个标志,知道注册状态是什么:您是否签署了背景事件。请注意,当用户看到视图控制器时(如果他来自另一个视图控制器)或者他是从主屏幕到视图控制器,您需要注册事件。
将视图控制器留给另一个视图控制器时,还需要取消注册。
简而言之:
斯威夫特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()
}