2012-04-27 1 views
15

Я чувствую, что не хватает трюк здесь ...Как сообщить активному контроллеру представления при вызове applicationDidBecomeActive?

Я просто хочу, чтобы позвонить viewDidLoad или viewDidAppear на текущем активном контроллере представления, когда applicationDidBecomeActive вызывается, так что я могу восстановить некоторые анимации или любой другой, когда приложение запускается снова с фона. Некоторые из моих взглядов не волнуют, но другим действительно нужно знать.

Я использую раскадровки, а файл делегата моего приложения имеет стандартные функции, но все с помощью ПУСТОЙ тел. Например, didFinishLaunchingWithOptions просто возвращает YES и ничего не делает. Раскадровка автоматически делает все, что я думаю.

Так как я могу поговорить с текущим контроллером представления из моего довольно пустого, свободного от информации, делегата приложения?

+0

Там очень хорошо может быть более простым способом сделать это, но я думаю, что это будет работать, если добавить свойство на вашем приложение делегат @property (сильный, неатомический) UIViewController * currentViewController. И затем каждый раз, когда вы загружаете представление, перейдите к делегату, чтобы установить это свойство.А затем в applicationWillResignActive сохраните его в NSUserDefaults и проверьте значение, когда приложение снова активируется? – geraldWilliam

ответ

20

Я бы порекомендовал использовать уведомления.

В applicationdidBecomeActive методе своего приложения делегата поставить этот код:

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

В методе инициализации вашего текущего активного контроллера представления подписаться на уведомление.

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

Реализовать метод «updateStuff» в контроллере, и вы должны быть в состоянии делать то, что вы хотите, когда приложение становится активным.

+0

Спасибо, что отлично поработал, казалось, самый изысканный подход предложенных. Хотя я немного беспокоюсь о том, чтобы правильно удалить наблюдателя. Я использую кучу ViewControllers по модулю, чтобы они загружались и выгружались много. Я вызываю addObserver в - (void) viewDidLoad removeObserver в - (void) viewDidUnload. Кажется, работает нормально. Я буду тестировать дальше ... –

+0

Не забудьте сделать [[NSNotificationCenter defaultCenter] removeObserver: self name: @ "appDidBecomeActive" object: nil]; in viewDidUnload –

+2

Не забудьте удалитьObserver в dealloc, так как viewDidUnload не будет вызван во всех многих сценариях –

0

Вместо того, чтобы пытаться отслеживать, какой ViewController является текущим, вы можете отправить NSNotification из своего AppDelegate и подписаться на него в своем ViewController. Таким образом, контроллер просмотра отслеживает, нужно ли емузывать viewDidAppear.

+0

Да, это то, с чем я пошел. Делает общий смысл, так как большинство моих контроллеров не нужно регистрироваться. –

0

ваш AppDelegate будет иметь свойство window, это окно будет иметь свойство rootViewController. Здесь вы можете найти свой viewController.

Если вы используете TabBarController, rootviewcontroller будет tabbarcontroller, и вы можете вызвать выбранный контрольный контроллер tabbarcontroller, чтобы получить текущий 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.

+0

Это свойство окна не работает для меня, оно дает мне эту ошибку: использование незаявленного идентификатора «окно». Не могли бы вы обновить ответ, потому что мне действительно нужно знать, какой вид на экране, а затем обновить его. – Hamid

+0

@Rose см. Обновление –

+0

Спасибо за обновление, я изменил его, и он выдает исключение следующим образом: 'unrecognized selector sent to instance' :(для этой строки кода:' UIViewController * vc = tabbarController.selectedViewController; ' – Hamid

51

Вместо отправки уведомления от вашего приложения делегата, операционная система отправляет уведомление автоматически, что вы можете наблюдать:

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

и, конечно же, не забудьте остановить наблюдения незадолго до или внутри вашего метода dealloc, позвонив по телефону :

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

Это лучшее решение, чем принятый в настоящее время ответ Брэндона Броджески. – MattyG

+2

это правильный способ сделать это – nilloc

1

Swift версия:

Вы можете добавить эту строку в вашем viewDidLoad

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

func viewDidBecomeActive(){ 
    print("viewDidBecomeActive") 
} 
Смежные вопросы