Как узнать активный контроллер представления при вызове 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()
}