UIViewController: вызывается viewWillAppear, viewDidAppear not

В подклассе UIViewController у меня есть следующие методы:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // do something
    myTextField.text = @"Default";
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // do something
    [myTextField selectAll:self];
    [myTextField becomeFirstResponder];
}

- (void)viewDidLoad {
    [super viewDidLoad];    
    // do something
    myTextField.delegate = self;
}

NIB создан с помощью Interface Builder. Соответствующий объект контроллера просмотра перемещается контроллером навигации через pushViewController.

Предшествующее поведение - показать текстовую запись по умолчанию в текстовом поле, выбрать весь текст и установить текстовое поле в качестве первого ответчика. [Edit: Я заметил, что выбор всех и создание первого ответчика не имеет смысла, поскольку выбор исчезнет; все же, мне интересно, почему методы ведут себя так, как описано ниже.]

Тем не менее, , пока вызываются методы viewDidLoad и viewWillAppear, метод viewDidAppear не вызывается. Может кто-нибудь сказать мне, почему? Большинство вопросов, которые я нашел в Интернете, и здесь рассматриваются как viewWillAppear/viewDidAppear, не работают; Я также понял, что в подвидных или программно созданных представлениях эти методы не вызываются; но это не применяется в случае, и я также удивляюсь, почему один из этих методов "жизненного цикла" вызван, а другой нет.

Любая идея? Спасибо!

Ответы

Ответ 1

У меня была эта проблема со мной: viewWillAppear вызывался, но viewDidAppear не был!

Наконец-то я понял, что это произошло потому, что у меня был tabBarController, где я перегрузил его собственный viewDidAppear и забыл [super viewDidAppear:animated];

Он отбрасывает каждый VC на каждой вкладке! добавив, что эта строка была исправлена ​​для моего другого VC's.

Надеюсь, это поможет кому-то!

Ответ 2

Вызов viewDidAppear: должен всегда следовать за viewWillAppear:, если вы не делаете что-то обычное, что, как вы говорите, нет. Я не знаю, почему это не работает, но вот несколько идей:

Может быть, вы делаете что-то странное в одном из методов делегата для UITextFieldDelegate? Вряд ли это повлияло бы на viewDidAppear:, но это может быть преступником.

Вы загрузили много материала в память, прежде чем нажимать вид? Я не уверен, что произойдет, если вы получите предупреждение о памяти между viewWillAppear: и viewDidAppear:.

Вы пытались сделать "Чистый"? Иногда это может помочь.

В таких случаях, когда это должно сработать, я обычно создаю новый класс и представляю функциональность, когда-либо, чтобы посмотреть, смогу ли я заставить ее работать таким образом. Я попробовал свой код в новом проекте навигация, где я добавил новый UIViewController с выходом в текстовое поле. Затем я вставил код из вопроса, и он работал так, как ожидалось.

Ответ 3

У меня была та же проблема.

У меня была копия/вставка viewDidAppear, чтобы создать viewWillAppear, но забыл изменить вызов super.viewDidAppear(). Это, казалось, остановило viewDidAppear от вызова.

Похоже, что где-то в вашем коде вы пропустили или перепутали вызов суперкласса.

Ответ 4

Это может быть связано с тем, что вы добавили контроллер дочернего представления в ваш родительский VC в viewDidLoad или viewWillAppear. Внешний вид ребенка запрещает вызов viewDidAppear.

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

Ответ 5

В одном случае вызывается viewWillAppear, а viewDidAppear - нет.

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

Таким образом, вы не закончите свайп и останетесь на втором контроллере, и viewDidAppear не будет вызван с первого контроллера.