Как узнать активный контроллер представления при вызове applicationDidBecomeActive?
Я чувствую, что здесь не хватает трюка...
Я просто хочу вызвать viewDidLoad или viewDidAppear в текущем активном контроллере представления при вызове applicationDidBecomeActive, поэтому я могу reset некоторые анимации или что-то еще, когда приложение снова запускается из фона. Некоторые из моих взглядов не волнуют, но другим действительно нужно знать.
Я использую раскадровки, а файл делегата моего приложения имеет стандартные функции, но все с элементами EMPTY. Например, didFinishLaunchingWithOptions просто возвращает YES и ничего не делает. Раскадровка автоматически делает все, что я думаю.
Итак, как я могу поговорить с текущим контроллером представления из моего довольно пустого, бесплатного делегата приложения?
Ответы
Ответ 1
Я бы рекомендовал использовать уведомления.
В приложении приложения делегирования applicationdidBecomeActive введите этот код:
[[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];
В вашем текущем активном методе проверки контроллера подписки на уведомление.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateStuff)
name:@"appDidBecomeActive"
object:nil];
Внесите в свой контроллер метод updateStuff, и вы сможете делать все, что захотите, когда приложение станет активным.
Ответ 2
Вместо отправки уведомления от вашего делегата приложения ОС автоматически отправляет уведомление, которое вы можете наблюдать:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initSongInfo)
name:UIApplicationDidBecomeActiveNotification
object:nil];
и, конечно же, обязательно прекратите наблюдение когда-нибудь раньше или в вашем методе dealloc, позвонив:
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
Ответ 3
Быстрая версия:
Вы можете добавить эту строку в свой видDidLoad
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)
func viewDidBecomeActive(){
print("viewDidBecomeActive")
}
Ответ 4
Вместо того, чтобы пытаться отслеживать, какой ViewController является текущим, вы можете отправить NSNotification из своего AppDelegate и подписаться на него в своем ViewController. Таким образом, контроллер просмотра отслеживает, нужно ли ему вызвать viewDidAppear.
Ответ 5
ваш 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];
Если у вас более сложная иерархия представлений с навигационными контроллерами или модальными представлениями, вы можете вызвать представленныйViewController или topViewController.
Ответ 6
Хорошо, это довольно катастрофично.
Вы, ребята, должны обращать внимание на регистрацию/отмену регистрации событий, так как это может привести к утечке памяти.
Чтобы все работало, вам нужно установить флажок, который знает, что такое статус регистрации: либо вы подписаны на фоновые события, либо нет. Обратите внимание, что вам нужно зарегистрироваться в событиях, когда пользователь видит контроллер представления (если он пришел из другого) или если он пришел с домашнего экрана на ваш контроллер представления.
Вам также необходимо отменить регистрацию, когда вы оставляете контроллер вида другим.
Короче:
Свифт 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()
}