спасибо BoltClock, но, пожалуйста, дайте мне пример того и другого, если возможно ..
PJR
3
@BoltClock было бы неплохо, если бы это было правдой. Я предполагаю, что 15 человек, проголосовавших за, прочитали название метода, но никогда не измерили его ... Пришли сюда из Google, потому что это НЕ разница между ними
Адам
1
В частности: parentView.viewDidAppear вызывается ДОЛГОЕ ВРЕМЯ до того, как Apple фактически отображает parentView ... Apple сначала (атомарно) рисует все подпредставления ... и если у вас много подпредставлений или сложных, тогда "viewDidAppear" можно назвать десятками или на сотни миллисекунд раньше :(.
Адам
Ответы:
292
В общем, что делаю:
1) ViewDidLoad - всякий раз, когда я добавляю элементы управления к представлению, которое должно отображаться вместе с представлением, я сразу же помещаю его в метод ViewDidLoad. Обычно этот метод вызывается всякий раз, когда представление загружается в память. Так, например, если мое представление представляет собой форму с 3 метками, я бы добавил сюда метки; представление никогда не будет существовать без этих форм.
2) ViewWillAppear : обычно я использую ViewWillAppear только для обновления данных в форме. Итак, в приведенном выше примере я бы использовал это, чтобы фактически загрузить данные из моего домена в форму. Создание UIViews довольно дорогое, и вам следует по возможности избегать этого в методе ViewWillAppear, потому что когда он вызывается, это означает, что iPhone уже готов показать UIView пользователю, и все, что вы здесь делаете будет заметно влиять на производительность (например, задержка анимации и т. д.).
3) ViewDidAppear : наконец, я использую ViewDidAppear для запуска новых потоков к вещам, выполнение которых потребует много времени, например, выполнение вызова веб-службы для получения дополнительных данных для формы выше. Хорошо то, что, поскольку представление уже существует и отображается для пользователя, вы можете показать пользователю приятное сообщение «Ожидание», пока вы получаете данные.
Извините, но что вы имеете в виду, говоря «загрузить данные из моего домена в форму» viewWillAppear? Вы имеете ввиду скачивание через сеть? Но вы также предлагаете загружать файлы viewDidAppear?
Этот ответ должен быть в документации. Это действительно помогло прояснить разницу между тремя методами. Спасибо!
GangstaGraham
1
+1 Я немного запутался, понимая разницу между этими тремя, но вы только что прояснили это более чем идеально @ChetanBhalara
Chisx
@ChetanBhalara, но если вы будете много работать над этим, ViewDidAppearвы легко запутаете пользователя в пользовательском интерфейсе :)
hqt
46
viewDidLoad === >>> Поместите сюда свой код инициализации. Не помещайте динамические данные, которые могут измениться в течение жизненного цикла представления. Итак, если вы извлекаете данные из основных данных, вы не хотите делать это здесь, если это может измениться в течение жизни представления. Например: скажем, у вас есть контроллер вкладок. Вы переключаетесь с tab1 на tab2 и что-то меняете в модели на tab2. Если вы вернетесь к tab1 и код вашей модели был выполнен в viewDidLoad, он не будет обновлен (при условии, что вы не используете KVO или NSFetchedResultsController и т. Д.).
viewWillAppear === >>> Это вызывается каждый раз, когда представление собирается появиться, вне зависимости от того, находится оно уже в памяти или нет. Поместите сюда свой динамический код, например логику модели.
viewDidAppear === >>> Поместите сюда дорогостоящие операции, которые вы хотите выполнять, только если вы уверены, что представление находится на экране, например, сетевые вызовы.
Примечание: если ваше приложение находится в фоновом режиме и возвращается на передний план, вам необходимо обработать это с помощью NSNotificationCenter. Я написал код для этого в комментариях ниже. Вы можете подумать, что viewWillAppear / viewDidAppear сработает. Поставьте там точку останова и проверьте ее. Не стреляет. Итак, если что-то изменилось в вашем приложении, пока оно работало в фоновом режиме, вам необходимо обновить это с помощью уведомлений.
Запускается ли ViewWill или ViewDid каждый раз, когда вы снимаете сворачивание приложения?
Jeef 02
2
@Jeef Это отличный вопрос. Ни один из них не запускается, если приложение не убито системой или пользователем в фоновом режиме. Что вам нужно сделать, чтобы получить уведомление, когда приложение не свернуто, вы должны использовать NSNotificationCenter и addObserver для имени UIApplicationWillEnterForegroundNotification. Селектор должен быть applicationWillEnterForeground: у него есть параметр NSNotification. Поместите свой код в этот метод для перезагрузки данных и т. Д. Что вы можете сделать, так это создать метод перезагрузки, который вы вызываете из этого метода, а также viewDidAppear, если они должны быть одинаковыми.
smileBot 02
2
@Jeef что-то вроде этого: - (void) viewDidLoad {[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (applicationWillEnterForeground :) name: UIApplicationWillEnterForegroundNotification object: nil]; } - (void) applicationWillEnterForeground: (NSNotification *) notif {// ответить здесь чем угодно}
smileBot 02
12
viewWillAppearМетод вызывается перед загрузкой фактического представления.
viewDidAppearМетод вызывается , когда представление уже загружен, и вы хотите , чтобы показать что - то.
viewWillAppear:
■ Вызывается перед добавлением представления в иерархию представлений окон
■ Вызывается перед [vc.view layoutSubviews] (при необходимости) viewDidAppear :
■ Вызывается после добавления представления в иерархию представлений
■ Вызывается после [vc.view layoutSubviews] (если необходимо)
viewDidLoadМетод вызывается , когда представление первого экземпляра. IBOutletссылки подключаются к моменту вызова, но не раньше. Однако frameточка зрения может не быть установлена к тому времени, когда это было вызвано. Это отличное место для добавления / настройки подвидов и связанных с ними ограничений. Но если вы выполняете любую ручную настройку frameзначений на основе размеров основного представления, настройку этих фреймов следует отложить до viewWillAppearили viewDidLayoutSubviews.
viewWillAppearМетод вызывается , когда представление вида в иерархии представлений собирается начать. Примечательно, что это вызывается в начале анимации (если есть) представления представления. Его компаньон, viewWillDisappearочевидно , вызывается, когда начинается переход от этой точки зрения.
viewDidAppearМетод вызывается , когда делается презентация зрения, в частности , когда - либо , и все связанные с ним анимация завершена. Его компаньон, viewDidDisappearочевидно , вызывается, когда выполняется переход от этого представления.
Два важных предостережения:
viewDidLoadвызывается один раз и только один раз, когда представление создается впервые. С другой стороны, viewWillAppearи viewDidAppearбудет вызываться не только при первом представлении представления, но и каждый последующий раз при повторном представлении того же представления. Например, когда вы впервые представляете представление, будут вызваны все три этих метода. Если рассматриваемое представление впоследствии представляет другое представление, которое впоследствии отклоняется, viewWillAppearи viewDidAppearобычно будет вызываться снова, когда рассматриваемое представление добавляется и анимируется обратно в иерархию представлений, но viewDidLoadне будет. viewDidLoadвызывается только при первом создании этого конкретного экземпляра.
Итак, если вы хотите что-то делать каждый раз, когда представление снова появляется (например, вы закрываете его или возвращаетесь к нему), делайте это в viewWillAppearили viewDidAppear. Если вы хотите, чтобы это происходило только при первом создании экземпляра представления, сделайте это в viewDidLoad.
Вызов viewWillAppearне гарантирует, что переход к этому представлению когда-либо будет завершен. Примечательно, что если вы используете интерактивный переход, управляемый пользователем в режиме реального времени, но этот интерактивный переход можно отменить. Т.е. только потому, что viewWillAppearвызывается, это не значит, что viewDidAppearбудет вызван. Обычно это так, но если интерактивный жест отменяется, этого не происходит (потому что переход никогда не завершался).
На WWDC 2013 в контексте интерактивных переходов ведущий пошутил, что их следует переименовать viewWillAppearв « viewMightAppear, или viewWillProbablyAppear, или iReallyWishThisViewWouldAppear».
Примером встроенного интерактивного жеста является использование, UINavigationControllerи вы «проводите пальцем от левого края», чтобы инициировать всплывающее окно представления. viewWillAppearБудет вызываться для представления , к которому вы выскакивают, но если вы отмените , что «листайте левого края» , чтобы вернуться к просмотру , с которого вы начали это поп жест, поп отменяется , и viewDidAppearдля представления вы начали вернуться к никогда не будет вызван.
В viewWillAppearитоге вы должны быть осторожны и не писать код, предполагающий, что за каждым вызовом в конечном итоге последует вызов viewDidAppear. Если переход отменен, этого не произойдет.
viewwillappear будет вызывать перед загрузкой представления, чтобы вы могли выполнить определенную задачу перед загрузкой этого представления, а viewdidappear вызовет после загрузки представления, чтобы задача публикации была выполнена в этом методе
Разница между «will» и «did» ... Как следует из названия, viewWillAppear вызывается до того, как представление собирается появиться, а viewDidAppear вызывается, когда представление действительно появилось.
посмотрите на принятый ответ, братан, который содержит 70+ голосов. :)
PJR
4
1) ViewWillAppear : представление, фактически загруженное в память, вызывается один раз в контроллере представления и имеет свой фрейм, но все еще не отображается для пользователя
2) ViewDidAppear : контроллер, добавленный в иерархию представлений, чтобы вы могли представить их следующему контроллеру, а также представление компоновало подвиды.
Как следует из названия, viewWillAppearвызывается перед тем, как представление собирается появиться, и viewDidAppearвызывается, когда представление действительно появилось.
Вариант использования , т.е. когда я должен использовать какой?
viewDidLoad - когда метки, кнопки (т.е. любые элементы управления / подпредставления) подключены к файлу интерфейса представления, и если вы хотите загрузить все это одновременно с представлением ViewController, и если вы хотите загрузить это в память один раз и быть покончено с этим
viewWillAppear- скажем, вы хотите изменять цвет фона представления каждый раз, когда на экране появляется viewController. Или, что более реалистично, если вам нужен цвет фона DarkMode в ночное время дня и светлый цвет фона в дневное время, используйте этот код вviewWillAppear
Также обратите внимание, что, если вы используете стек навигации ( UINavigationController), viewController, который должен быть извлечен, имеет viewWillDisappear()вызываемый, а ViewController, который в следующий раз будет на вершине стека, будет viewWillAppear()вызывать
Ответы:
В общем, что делаю:
1) ViewDidLoad - всякий раз, когда я добавляю элементы управления к представлению, которое должно отображаться вместе с представлением, я сразу же помещаю его в метод ViewDidLoad. Обычно этот метод вызывается всякий раз, когда представление загружается в память. Так, например, если мое представление представляет собой форму с 3 метками, я бы добавил сюда метки; представление никогда не будет существовать без этих форм.
2) ViewWillAppear : обычно я использую ViewWillAppear только для обновления данных в форме. Итак, в приведенном выше примере я бы использовал это, чтобы фактически загрузить данные из моего домена в форму. Создание UIViews довольно дорогое, и вам следует по возможности избегать этого в методе ViewWillAppear, потому что когда он вызывается, это означает, что iPhone уже готов показать UIView пользователю, и все, что вы здесь делаете будет заметно влиять на производительность (например, задержка анимации и т. д.).
3) ViewDidAppear : наконец, я использую ViewDidAppear для запуска новых потоков к вещам, выполнение которых потребует много времени, например, выполнение вызова веб-службы для получения дополнительных данных для формы выше. Хорошо то, что, поскольку представление уже существует и отображается для пользователя, вы можете показать пользователю приятное сообщение «Ожидание», пока вы получаете данные.
источник
viewWillAppear
? Вы имеете ввиду скачивание через сеть? Но вы также предлагаете загружать файлыviewDidAppear
?ViewDidAppear
вы легко запутаете пользователя в пользовательском интерфейсе :)viewDidLoad === >>> Поместите сюда свой код инициализации. Не помещайте динамические данные, которые могут измениться в течение жизненного цикла представления. Итак, если вы извлекаете данные из основных данных, вы не хотите делать это здесь, если это может измениться в течение жизни представления. Например: скажем, у вас есть контроллер вкладок. Вы переключаетесь с tab1 на tab2 и что-то меняете в модели на tab2. Если вы вернетесь к tab1 и код вашей модели был выполнен в viewDidLoad, он не будет обновлен (при условии, что вы не используете KVO или NSFetchedResultsController и т. Д.).
viewWillAppear === >>> Это вызывается каждый раз, когда представление собирается появиться, вне зависимости от того, находится оно уже в памяти или нет. Поместите сюда свой динамический код, например логику модели.
viewDidAppear === >>> Поместите сюда дорогостоящие операции, которые вы хотите выполнять, только если вы уверены, что представление находится на экране, например, сетевые вызовы.
Примечание: если ваше приложение находится в фоновом режиме и возвращается на передний план, вам необходимо обработать это с помощью NSNotificationCenter. Я написал код для этого в комментариях ниже. Вы можете подумать, что viewWillAppear / viewDidAppear сработает. Поставьте там точку останова и проверьте ее. Не стреляет. Итак, если что-то изменилось в вашем приложении, пока оно работало в фоновом режиме, вам необходимо обновить это с помощью уведомлений.
источник
viewWillAppear
Метод вызывается перед загрузкой фактического представления.viewDidAppear
Метод вызывается , когда представление уже загружен, и вы хотите , чтобы показать что - то.источник
viewWillAppear:
■ Вызывается перед добавлением представления в иерархию представлений окон
■ Вызывается перед [vc.view layoutSubviews] (при необходимости)
viewDidAppear :
■ Вызывается после добавления представления в иерархию представлений
■ Вызывается после [vc.view layoutSubviews] (если необходимо)
источник
Несколько замечаний:
viewDidLoad
Метод вызывается , когда представление первого экземпляра.IBOutlet
ссылки подключаются к моменту вызова, но не раньше. Однакоframe
точка зрения может не быть установлена к тому времени, когда это было вызвано. Это отличное место для добавления / настройки подвидов и связанных с ними ограничений. Но если вы выполняете любую ручную настройкуframe
значений на основе размеров основного представления, настройку этих фреймов следует отложить доviewWillAppear
илиviewDidLayoutSubviews
.viewWillAppear
Метод вызывается , когда представление вида в иерархии представлений собирается начать. Примечательно, что это вызывается в начале анимации (если есть) представления представления. Его компаньон,viewWillDisappear
очевидно , вызывается, когда начинается переход от этой точки зрения.viewDidAppear
Метод вызывается , когда делается презентация зрения, в частности , когда - либо , и все связанные с ним анимация завершена. Его компаньон,viewDidDisappear
очевидно , вызывается, когда выполняется переход от этого представления.Два важных предостережения:
viewDidLoad
вызывается один раз и только один раз, когда представление создается впервые. С другой стороны,viewWillAppear
иviewDidAppear
будет вызываться не только при первом представлении представления, но и каждый последующий раз при повторном представлении того же представления. Например, когда вы впервые представляете представление, будут вызваны все три этих метода. Если рассматриваемое представление впоследствии представляет другое представление, которое впоследствии отклоняется,viewWillAppear
иviewDidAppear
обычно будет вызываться снова, когда рассматриваемое представление добавляется и анимируется обратно в иерархию представлений, ноviewDidLoad
не будет.viewDidLoad
вызывается только при первом создании этого конкретного экземпляра.Итак, если вы хотите что-то делать каждый раз, когда представление снова появляется (например, вы закрываете его или возвращаетесь к нему), делайте это в
viewWillAppear
илиviewDidAppear
. Если вы хотите, чтобы это происходило только при первом создании экземпляра представления, сделайте это вviewDidLoad
.Вызов
viewWillAppear
не гарантирует, что переход к этому представлению когда-либо будет завершен. Примечательно, что если вы используете интерактивный переход, управляемый пользователем в режиме реального времени, но этот интерактивный переход можно отменить. Т.е. только потому, чтоviewWillAppear
вызывается, это не значит, чтоviewDidAppear
будет вызван. Обычно это так, но если интерактивный жест отменяется, этого не происходит (потому что переход никогда не завершался).На WWDC 2013 в контексте интерактивных переходов ведущий пошутил, что их следует переименовать
viewWillAppear
в «viewMightAppear
, илиviewWillProbablyAppear
, илиiReallyWishThisViewWouldAppear
».Примером встроенного интерактивного жеста является использование,
UINavigationController
и вы «проводите пальцем от левого края», чтобы инициировать всплывающее окно представления.viewWillAppear
Будет вызываться для представления , к которому вы выскакивают, но если вы отмените , что «листайте левого края» , чтобы вернуться к просмотру , с которого вы начали это поп жест, поп отменяется , иviewDidAppear
для представления вы начали вернуться к никогда не будет вызван.В
viewWillAppear
итоге вы должны быть осторожны и не писать код, предполагающий, что за каждым вызовом в конечном итоге последует вызовviewDidAppear
. Если переход отменен, этого не произойдет.источник
viewwillappear будет вызывать перед загрузкой представления, чтобы вы могли выполнить определенную задачу перед загрузкой этого представления, а viewdidappear вызовет после загрузки представления, чтобы задача публикации была выполнена в этом методе
источник
Разница между «will» и «did» ... Как следует из названия, viewWillAppear вызывается до того, как представление собирается появиться, а viewDidAppear вызывается, когда представление действительно появилось.
источник
1) ViewWillAppear : представление, фактически загруженное в память, вызывается один раз в контроллере представления и имеет свой фрейм, но все еще не отображается для пользователя
2) ViewDidAppear : контроллер, добавленный в иерархию представлений, чтобы вы могли представить их следующему контроллеру, а также представление компоновало подвиды.
источник
Первое происходит до появления представления, а второе - после.
источник
Подводить итоги:
-viewWillAppear -> обновить данные (перезагрузить данные из табличного представления)
-viewDidAppear -> дорогие операции (вызов API с хорошим индикатором прогресса!)
источник
Как следует из названия,
viewWillAppear
вызывается перед тем, как представление собирается появиться, иviewDidAppear
вызывается, когда представление действительно появилось.источник
Вариант использования , т.е. когда я должен использовать какой?
viewDidLoad
- когда метки, кнопки (т.е. любые элементы управления / подпредставления) подключены к файлу интерфейса представления, и если вы хотите загрузить все это одновременно с представлением ViewController, и если вы хотите загрузить это в память один раз и быть покончено с этимviewWillAppear
- скажем, вы хотите изменять цвет фона представления каждый раз, когда на экране появляется viewController. Или, что более реалистично, если вам нужен цвет фона DarkMode в ночное время дня и светлый цвет фона в дневное время, используйте этот код вviewWillAppear
Еще один хороший вариант использования здесь https://stackoverflow.com/a/39395865/5438240
Также обратите внимание, что, если вы используете стек навигации (
UINavigationController
), viewController, который должен быть извлечен, имеетviewWillDisappear()
вызываемый, а ViewController, который в следующий раз будет на вершине стека, будетviewWillAppear()
вызыватьисточник