ViewDidAppear не вызывается при открытии приложения из фона

У меня есть View Controller, в котором мое значение равно 0 (метка), и когда я открываю этот View Controller из другого ViewController Я поставил viewDidAppear установить значение 20 на этикетке. Это работает нормально, но когда я закрываю свое приложение и затем снова я открываю свое приложение, но значение не меняется, потому что viewDidLoad, viewDidAppear а также viewWillAppear ничего не вызывать. Как я могу позвонить, когда я открою свое приложение. Должен ли я сделать что-нибудь из applicationDidBecomeActive?

8 ответов

Решение

Заинтересовавшись точной последовательностью событий, я оснастил приложение следующим образом: (@Zohaib, вы можете использовать приведенный ниже код NSNotificationCenter, чтобы ответить на ваш вопрос).

// AppDelegate.m

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"app will enter foreground");
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    NSLog(@"app did become active");
}

// ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"view did load");

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (void)appDidBecomeActive:(NSNotification *)notification {
    NSLog(@"did become active notification");
}

- (void)appWillEnterForeground:(NSNotification *)notification {
    NSLog(@"will enter foreground notification");
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"view will appear");
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"view did appear");
}

При запуске вывод выглядит так:

2013-04-07 09:31:06.505 myapp[15459:11303] view did load
2013-04-07 09:31:06.507 myapp[15459:11303] view will appear
2013-04-07 09:31:06.511 myapp[15459:11303] app did become active
2013-04-07 09:31:06.512 myapp[15459:11303] did become active notification
2013-04-07 09:31:06.517 myapp[15459:11303] view did appear

Введите фон, затем снова введите передний план:

2013-04-07 09:32:05.923 myapp[15459:11303] app will enter foreground
2013-04-07 09:32:05.924 myapp[15459:11303] will enter foreground notification
2013-04-07 09:32:05.925 myapp[15459:11303] app did become active
2013-04-07 09:32:05.926 myapp[15459:11303] did become active notification

Использование Objective-C

Вы должны зарегистрировать UIApplicationWillEnterForegroundNotification в вашем ViewController"s viewDidLoad метод и всякий раз, когда приложение возвращается из фона, вы можете делать все, что вы хотите сделать в методе, зарегистрированном для уведомления. ViewControllerviewWillAppear или viewDidAppear не будут вызываться при возврате приложения из фона на передний план.

-(void)viewDidLoad{

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doYourStuff)

  name:UIApplicationWillEnterForegroundNotification object:nil];
}

-(void)doYourStuff{

   // do whatever you want to do when app comes back from background.
}

Не забудьте отменить регистрацию уведомления, на которое вы зарегистрированы.

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Обратите внимание, если вы зарегистрируете свой viewController за UIApplicationDidBecomeActiveNotification тогда ваш метод будет вызываться каждый раз, когда ваше приложение станет активным, регистрация не рекомендуется viewController для этого уведомления.

Использование Swift

Для добавления наблюдателя вы можете использовать следующий код

 override func viewDidLoad() {
    super.viewDidLoad()

     NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
     UIApplicationWillEnterForegroundNotification, object: nil)
 }

 func doYourStuff(){
     // your code
 }

Для удаления наблюдателя вы можете использовать функцию deinit swift.

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

Версия Swift 3.0 ++

В вашем viewDidLoad, зарегистрируйтесь в центре уведомлений, чтобы прослушать это открытое из фонового действия

NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)

Затем добавьте эту функцию и выполните необходимые действия

func doSomething(){
    //...
}

Наконец добавьте эту функцию, чтобы очистить наблюдателя уведомлений, когда ваш контроллер представления разрушен.

deinit {
    NotificationCenter.default.removeObserver(self)
}

Свифт 4.2. версия

Зарегистрируйтесь в Центре уведомлений в viewDidLoad получать уведомления, когда приложение возвращается из фона

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)

Реализуйте метод, который должен быть вызван.

@objc private func doSomething() {
    // Do whatever you want, for example update your view.
}

Вы можете удалить наблюдателя, как только ViewController уничтожен Это требуется только ниже iOS9 и MacOS 10.11

deinit {
    NotificationCenter.default.removeObserver(self)
}

Я думаю, что регистрация для UIApplicationWillEnterForegroundNotification опасна, так как вы можете получить более одного контроллера, реагирующего на это уведомление. Ничто не гарантирует, что эти контроллеры все еще видны при получении уведомления.

Вот что я делаю: я принудительно вызываю viewDidAppear на активном контроллере прямо из делегата приложения метода didBecomeActive:

Добавьте код ниже, чтобы - (void)applicationDidBecomeActive:(UIApplication *)application

UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
    activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];

Просто зарегистрируйте свой контроллер вида для UIApplicationWillEnterForegroundNotification уведомление и реагировать соответственно.

Попробуйте добавить это в AppDelegate applicationWillEnterForeground.

func applicationWillEnterForeground(_ application: UIApplication) {        
    // makes viewWillAppear run
    self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
    self.window?.rootViewController?.endAppearanceTransition()
}

Согласно документации Apple:

(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;

Описание:
Сообщает дочернему контроллеру, что его внешний вид скоро изменится. Если вы реализуете пользовательский контроллер контейнера, используйте этот метод, чтобы сообщить дочернему элементу о том, что его представления должны появиться или исчезнуть. Не призывать viewWillAppear: , viewWillDisappear: , viewDidAppear: , или же viewDidDisappear: напрямую

(void)endAppearanceTransition;

Описание:

Сообщает дочернему контроллеру, что его внешний вид изменился. Если вы реализуете пользовательский контроллер контейнера, используйте этот метод, чтобы сообщить дочернему элементу, что переход представления завершен.

Образец кода:

(void)applicationDidEnterBackground:(UIApplication *)application
{

    [self.window.rootViewController beginAppearanceTransition: NO animated: NO];  // I commented this line

    [self.window.rootViewController endAppearanceTransition]; // I commented this line

}

Вопрос: как я исправил?

Ответ: Я нашел этот кусок строк в приложении. Эти строки заставили мое приложение не получать никаких уведомлений ViewWillAppear. Когда я прокомментировал эти строки, все работает нормально.

Другие вопросы по тегам