ViewWillAppear не запускается при использовании addSubView!

Я застрял! Я не понимаю, почему viewWillAppear не запускается в моем коде, но работает viewDidLoad. Если я правильно ее понимаю, viewDidLoad запускается один раз в первом экземпляре, а viewWillAppear запускается каждый раз, когда представление добавляется в стек отображаемых представлений.

Я вижу, что у других была эта проблема, но некоторые, как их решения вызова viewWillAppear напрямую приводят к сбою моего приложения. Другие решения были связаны с навигационным контроллером и pushingView, но это не то, что я использую! Что мне не хватает?

Заранее благодарим за помощь!:)

См. ниже: View Controller # 1 - В настоящее время отображается на экране

-(IBAction)someButtonPressed:(id)sender{
  NSLog(@"FirstViewController - someButtonPressed");
  SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
  secondViewController.myLocation = self.myLocation;
  secondViewController.myDatabase = self.myDatabase;
  [self.view addSubview:secondViewController.view];
  //[secondViewController viewWillAppear:YES];
}

SecondViewController:

- (void)viewWillAppear:(BOOL)animated {
  NSLog(@"SecondViewController - viewWillAppear");
  [super viewWillAppear:animated];
  // updating ivars with data
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {   
    NSLog(@"SecondViewController - viewDidLoad");
    [super viewDidLoad];
}

Ответ 1

Если я правильно понимаю, viewDidLoad запускается один раз в первом экземпляре, а viewWillAppear запускается каждый раз, когда представление добавляется в стек отображаемых представлений.

-viewDidLoad вызывается каждый раз, когда загружается представление UIViewController. Это может быть много раз в течение одного времени работы контроллера, поскольку просмотр может быть выгружен для освобождения памяти, когда он не отображается и перезагружается, вызывая при необходимости другой вызов -viewDidLoad.

-viewWillAppear: вызывается, когда вид UIViewController становится видимым. Однако UIKit предполагает, что представления UIViewController заполнят их окно. Вложенные представления UIViewControllers являются примером злоупотребления UIViewControllers и приведут к неожиданному поведению. Как вы видели.

См. О контроллерах пользовательского вида в Руководстве по программированию контроллера просмотра для iOS:

Каждый созданный вами объект контроллера пользовательского вида отвечает за управление всеми представлениями в одной иерархии представлений. В приложениях iPhone представления в иерархии представлений традиционно охватывают весь экран, но в приложениях iPad они могут охватывать только часть экрана. Ключевое рассмотрение дизайна - это взаимно однозначное соответствие между контроллером представления и представлениями в его иерархии представлений. Вы не должны использовать несколько настраиваемых контроллеров представлений для управления различными частями одной и той же иерархии представлений. Аналогично, вы не должны использовать один настраиваемый объект контроллера просмотра для управления несколькими экранами, на которых стоит содержимое.

Ответ 2

Если вы написали пользовательский контейнер UIViewController, вы могли бы перезаписать следующий метод, который приведет к описанному поведению.

- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return NO;
}

В этом случае вам необходимо вручную обработать startAppearanceTransition/endAppearanceTransition. См. "Яблоки" Просмотр содержимого контроллера.

Ответ 3

viewWillAppear: вызывается, когда один вид обычного представления контроллер отображается одним из обычных способов (например, выбирая вкладку в UITabBarController, нажимая на UINavigationController, возвращаясь обратно в UINavigationController, будучи представленным presentModalViewController:animated, будучи обнаруженным после dismissModalViewControllerAnimated: и т.д.). Простое отображение представления с помощью addSubview: не вызывает метод.

Можно правильно вызвать viewWillAppear: вручную, но в целом лучше использовать один из обычных способов, упомянутых выше.

Ответ 4

Просто попробуйте это.. Я получил его работу:)

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated]; 
  NSLog(@"SecondViewController - viewWillAppear");

  // updating ivars with data
}

Ответ 5

Когда вы нажимаете view или представляете контроллер вида pushViewController: анимированный или presentModelViewController: анимированный:, они будут вызывать viewWillAppear: анимированные:, а также метод для вас. Но если вы addSubview: вручную, вам нужно вызвать этот метод самостоятельно.