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

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

Ответ 1

Интересно о точной последовательности событий, я применил приложение следующим образом: (@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

Ответ 2

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

Вы должны зарегистрировать UIApplicationWillEnterForegroundNotification в своем методе ViewController viewDidLoad, и всякий раз, когда приложение возвращается с фона, вы можете делать все, что хотите, в методе, зарегистрированном для уведомления. ViewController viewWillAppear или 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 быстрого доступа.

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

Ответ 3

Версия 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

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

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

Согласно документации 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

}

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

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