У чому різниця між -[UIViewController viewWillAppear:]
і -[UIViewController viewDidAppear:]
?
У чому різниця між -[UIViewController viewWillAppear:]
і -[UIViewController viewDidAppear:]
?
Відповіді:
Загалом, це те, що я роблю:
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
".
Приклад вбудованого інтерактивного жесту - це коли ви користуєтесь a UINavigationController
і "проведіть пальцем з лівого краю", щоб ініціювати спливаюче вікно перегляду. Заклик viewWillAppear
буде викликано для подання, на яке ви вискакуєте, але якщо ви скасуєте цей "пальцем з лівого краю", щоб повернутися до того виду, з якого ви розпочали цей поп-жест, спливаюче вікно скасовується, і viewDidAppear
для перегляду, який ви почали поп назад до ніколи не буде викликаний.
Чистий ефект цього полягає в тому, що ви повинні бути обережними, щоб ви не писали код, який передбачає, що після кожного дзвінка в viewWillAppear
кінцевому підсумку буде здійснено дзвінок на viewDidAppear
. Якщо перехід скасується, це не буде.
1) ViewWillAppear : Перегляд фактично завантажується в пам'ять, викликається один раз у контролері перегляду та має його кадр, але все ще не з’являється користувачеві
2) ViewDidAppear : Контролер додано до ієрархії подання, щоб ви могли представити наступний контролер, а також перегляд макетував підпогляди
Перше трапляється до появи подання, а останнє відбувається після цього.
Підсумовуючи:
-viewWillAppear -> оновити дані (перезавантажити дані з подання таблиці)
-viewDidAppear -> дорогі операції (API-дзвінок із приємною швидкістю прогресу!)
Usecase , тобто коли я повинен використовувати який?
viewDidLoad
- коли мітки, кнопки (i, e будь-які елементи управління / підпогляди) підключені до файлу інтерфейсу View, і якщо ви хочете завантажити все це одночасно з представленням ViewController, і якщо ви хочете один раз завантажити це в пам'ять і бути зроблено з ним
viewWillAppear
- скажімо, ви хочете змінити колір тла перегляду щоразу, коли на екрані з'явиться viewController. Або більш реалістично, якщо ви хочете, щоб колір фону DarkMode був у нічний час доби та світлий колір перегляду фону в денний час, перейдіть за цим кодом уviewWillAppear
Ще один добрий футляр тут https://stackoverflow.com/a/39395865/5438240
Також зауважте, що якщо ви використовуєте стек навігації ( UINavigationController
), viewController, який збирається спливати, має viewWillDisappear()
виклик, а ViewController, який буде розташований у верхній частині стека, буде viewWillAppear()
викликати