В чем разница между -viewWillAppear: и -viewDidAppear:?

В чем разница между -[UIViewController viewWillAppear:] и -[UIViewController viewDidAppear:]?

Ответ 1

В общем, это то, что я делаю:

1) ViewDidLoad. Когда я добавляю элементы управления в представление, которое должно появляться вместе с представлением, сразу же я помещаю его в метод ViewDidLoad. В основном этот метод вызывается всякий раз, когда представление загружается в память. Например, если мое представление представляет собой форму с тремя ярлыками, я бы добавил здесь метки; вид не будет существовать без этих форм.

2) ViewWillAppear. Обычно я использую ViewWillAppear для обновления данных в форме. Итак, в приведенном выше примере я бы использовал это, чтобы фактически загрузить данные из моего домена в форму. Создание UIView довольно дорого, и вам следует избегать, насколько это возможно, этого метода ViewWillAppear, потому что, когда это вызвано, это означает, что iPhone уже готов показать UIView пользователю, и все, что вы здесь делаете будет сильно влиять на производительность (например, задержка анимации и т.д.).

3) ViewDidAppear. Наконец, я использую ViewDidAppear для начала новых потоков для вещей, которые занимают много времени, например, для выполнения вызова webservice для получения дополнительных данных для формы выше. Хорошо, что, поскольку представление уже существует и отображается пользователю, вы можете показать приятное сообщение "Ожидание" пользователю, пока вы получите данные.

Ответ 2

viewDidLoad === → > Введите здесь код инициализации. Не ставьте динамические данные, которые могут измениться в течение жизненного цикла представления. Итак, если вы извлекаете данные из основных данных, вы не хотите делать это здесь, если это может измениться в течение жизни представления. Например: скажем, у вас есть контроллер табуляции. Вы переключаетесь с tab1 на tab2 и меняете что-то на модели в tab2. Если вы вернетесь к tab1, и ваш код модели был выполнен в viewDidLoad, это не будет обновлено (если вы не используете KVO или NSFetchedResultsController и т.д.).

viewWillAppear === → > Это вызывается каждый раз, когда будет отображаться представление, независимо от того, находится или нет представление уже в памяти. Поместите здесь свой динамический код, например, логику модели.

viewDidAppear === → > Поместите здесь дорогостоящие операции, которые вы только хотите сделать, если вы уверены, что просмотр на экране, например, для сетевых вызовов.

Обратите внимание: если ваше приложение связано с фоном и возвращается на передний план, вам необходимо обработать его с помощью NSNotificationCenter. Я написал код для этого в комментариях ниже. Вы можете подумать, что будет запущен viewWillAppear/viewDidAppear. Поместите там точку перерыва и проверьте ее. Он не срабатывает. Итак, если что-то изменилось для вашего приложения, когда оно было в фоновом режиме, вам нужно будет обновить его, используя уведомления.

Ответ 3

Метод viewWillAppear вызывается перед загрузкой фактического представления.

Метод viewDidAppear вызывается, когда представление уже загружено, и вы хотите что-то показать.

Ответ 4

viewWillAppear:
■ Вызывается перед добавлением представления в иерархию представлений окон

■ Вызывается перед [vc.view layoutSubviews] (при необходимости)
  viewDidAppear:
■ Вызывается после добавления представления в иерархию представлений
■ Вызывается после [vc.view layoutSubviews] (при необходимости)

Ответ 5

viewwillappear вызовет перед загрузкой представления, чтобы вы могли выполнить определенную задачу перед загрузкой этого представления, и viewdidappear вызовет после загрузки представления, чтобы post post выполнил этот метод

Ответ 6

Несколько замечаний:

  • Метод viewDidLoad вызывается при первом создании представления. Ссылки IBOutlet к тому времени, когда это было вызвано, но не раньше. Тем не менее, frame представления может быть не установлена к тому времени, когда это было вызвано. Это отличное место для добавления/настройки подпредставлений и связанных с ними ограничений. Но если вы выполняете какую-либо ручную настройку значений frame на основе измерений основного вида, конфигурация этих фреймов должна быть отложена до viewWillAppear или viewDidLayoutSubviews.

  • Метод viewWillAppear вызывается, когда начинается представление представления в иерархии представлений. Примечательно, что это вызывается в начале анимации (если есть) представления представления. Его компаньон viewWillDisappear явно вызывается, когда начинается переход от этого вида.

  • Метод viewDidAppear вызывается, когда viewDidAppear представление представления, особенно когда завершается любая связанная анимация. Его компаньон, viewDidDisappear, очевидно, viewDidDisappear, когда выполняется переход от этого представления.

Два важных предостережения:

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

    Поэтому, если вы хотите что-то делать каждый раз, когда представление появляется (например, вы закрываете или возвращаетесь к нему), делайте это в viewWillAppear или viewDidAppear. Если вы хотите, чтобы это происходило только при первом создании представления, сделайте это в viewDidLoad.

  • viewWillAppear не гарантирует, что переход к этому представлению когда-либо будет завершен. Примечательно, что если вы используете интерактивный переход, управляемый пользовательским вводом в реальном времени, но этот интерактивный переход можно отменить. viewWillAppear есть, просто потому что viewWillAppear, это не означает, что будет вызван viewDidAppear. Обычно это так, но если интерактивный жест отменен, он не будет (потому что переход не завершен).

    На WWDC 2013 в контексте интерактивных переходов докладчик пошутил, что ему следует переименовать viewWillAppear в " viewMightAppear, или viewWillProbablyAppear, или iReallyWishThisViewWouldAppear ".

    Примером встроенного интерактивного жеста является использование UINavigationController и вы "проводите от левого края", чтобы инициировать всплывающее представление. viewWillAppear будет вызываться для представления, к которому вы подключаетесь, но если вы отмените этот "удар с левого края", чтобы вернуться обратно к представлению, с которого вы начали этот поп-жест, всплывающее viewDidAppear отменяется, и viewDidAppear для представления, которое вы начал всплывать, чтобы никогда не будет называться.

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

Ответ 7

Разница между "волей" и "сделал"... Поскольку имя предполагает, что viewWillAppear вызывается до появления представления, и вызывается viewDidAppear при появлении представления.

Ответ 8

1) ViewWillAppear: представление, загруженное фактически в память, вызываемое один раз в контроллере представления и имевшее свой кадр, но все еще не отображаемое пользователю

2) ViewDidAppear: контроллер добавлен в иерархию представлений, так что вы можете представить следующему контроллеру, также представление делало макет подпредставлений

Ответ 9

Первое происходит до появления представления, и последнее происходит потом.

Ответ 10

Подводя итог:

-viewWillAppear → обновить данные (перезагрузить данные из табличного представления)

-viewDidAppear → дорогие операции (вызов API с хорошим продвижением hud!)

Ответ 11

Как следует из названия, вызывается viewWillAppear до появления представления и viewDidAppear вызывается при появлении представления.

Ответ 12

Usecase, то есть когда я должен использовать какой?

viewDidLoad - когда метки, кнопки (то есть любые элементы управления/подпредставления) подключены к файлу интерфейса View, и если вы хотите загрузить все это одновременно с ViewController View, и если вы хотите загрузить это в память один раз и покончим с этим

viewWillAppear - скажем, вы хотите менять цвет фона представления каждый раз, когда viewController появляется на экране. Или, если быть более реалистичным, если вам нужен цвет фона DarkMode в ночное время дня и светлый цвет фона в дневное время, используйте этот код в viewWillAppear

Еще один хороший пример использования здесь fooobar.com/info/18205/...

Также обратите внимание, что, если вы используете стек навигации, у viewController, который должен быть viewWillDisappear(), а у ViewController, который будет следующим на вершине стека, будет viewWillAppear()