UIViewController viewDidLoad vs. viewWillAppear: Який правильний розподіл праці?


164

Мені завжди було трохи незрозуміло щодо типу завдань, які слід призначити viewDidLoadvs viewWillAppear.: у UIViewControllerпідкласі.

наприклад, я роблю додаток, у якому UIViewControllerпідклас потрапляє на сервер, отримує дані, подає їх у подання, а потім відображає цей вид. Які плюси і мінуси цього робити в viewDidLoadпорівнянні з viewWillAppear?

Відповіді:


251

viewDidLoad - це те, що потрібно зробити один раз. viewWillAppear викликається щоразу, коли вигляд з’являється. Ви повинні робити те, що вам потрібно зробити один раз у viewDidLoad - як, наприклад, встановлення текстів UILabel. Однак ви можете змінити певну частину перегляду кожного разу, коли користувач перегляне його, наприклад, програма iPod прокручує тексти пісень у верхній частині кожного разу, коли ви переходите до подання "Зараз грає".

Однак, завантажуючи речі з сервера, ви також повинні думати про затримку. Якщо ви упакуєте все ваше мережеве спілкування в viewDidLoad або viewWillAppear, вони будуть виконані до того, як користувач побачить перегляд - можливо, це призведе до короткого заморожування вашої програми. Можливо, спочатку показати користувачеві незаселене представлення із певним індикатором активності. Коли ви закінчите роботу з вашою мережею, яка може зайняти секунду-дві (а може навіть вийти з ладу - хто знає?), Ви можете заповнити представлення даних своїми даними. Хороші приклади того, як це можна зробити, можна побачити у різних клієнтів Twitter. Наприклад, коли ви переглядаєте сторінку детальної інформації про автора в Twitterrific, у вікні відображається лише "Завантаження ...", поки мережеві запити не завершиться.


Отже, щодо viewWillAppear потенційно може бути викликано повторно. Чи запустить цей метод, якщо, наприклад, подання контролерів перегляду стає видимим після того, як його було приховано (я маю на увазі тут оклюдований, а не прихований метод на UIView). У якому сценарії виглядWillAppear буде викликаний, не передуючи йому викликом viewDidLoad?
dugla

7
viewDidLoad ТІЛЬКИ викликає виклик, коли побудовано представлення - так, наприклад, після виклику контролера перегляду initFromNibNamed, коли доступ до перегляду доступний. viewWillAppear викликається в будь-який час, коли ваш контролер подання не був у режимі перегляду, але потрапляє в поле перегляду - тому, коли ваш контролер перегляду натиснуто, виклик viewWillAppear. Якщо ви натиснете звідти інший підвід, і користувач повернеться, viewWillAppear буде викликаний знову.
Кендалл Гельмстетер Гельнер

Дякую Кендалл. Так, декілька стратегічно розміщених NSLogs розібрали мене. viewWillAppear / viewWillDissappear fire on viewcontroller push / pops.
dugla

3
Зауважте, що viewDidLoad ТАКОЖ буде викликатись, якщо подання приховано, а потім вивантажено з міркувань, пов’язаних із пам’яттю, а потім знову з’явиться. На що ви можете розраховувати: viewDidLoad називатиметься ОСТАННЯ ОДНІ при першому створенні подання та МОЖЛИВО частіше, коли подання знову з’являється після його приховання. viewWillAppear ЗАВЖДИ буде викликаний, коли подання відображається на екрані.
DanM

2
Чи може хтось прокоментувати далі ці два пов'язані питання: (1) Іноді, не завжди, значення фреймів для елементів керування (тобто, походження та розмір) у viewDidLoad нульові, а іноді ні - чому? (2) У шаблоні Apple для splitViewController''s detailView (iPad) є метод configureView - що має бути там у відношенні viewDidLoad та ViewWillAppear?
Джефф

12

Спочатку використовувався лише ViewDidLoad з tableView. Під час тестування з втратою Wi-Fi, встановивши пристрій на режим літака, зрозумів, що таблиця не оновлюється поверненням Wi-Fi. Насправді, схоже, немає можливості оновити tableView на пристрої, навіть натиснувши кнопку додому, у фоновому режимі встановлено ТАК у списку -Info.plist.

Моє рішення:

-(void) viewWillAppear: (BOOL) animated { [self.tableView reloadData];}

10

Важливо зазначити, що використання viewDidLoad для позиціонування є дещо ризикованим, і цього слід уникати, оскільки межі не встановлені. це може спричинити несподівані результати (у мене виникли різноманітні проблеми ...)

Це повідомлення досить добре описані різні методи та те, що відбувається в кожному з них.

В даний час для одноразового init та позиціонування я думаю про використання viewDidAppear із прапором, якщо у когось є якісь інші рекомендації, будь ласка, дайте мені знати.


погоджуйтеся з цим: "... слід уникати, оскільки межі не встановлені ..."
danisupr4

4

Залежить: чи потрібно вам завантажувати дані щоразу, коли ви відкриваєте подання? чи лише один раз ?

введіть тут опис зображення

  • Червоний: Їх не потрібно змінювати кожен раз. Після завантаження вони залишаються такими, якими вони були.
  • Фіолетовий: Їх потрібно змінювати з часом або після кожного завантаження. Ви не хочете бачити тих самих трьох запропонованих користувачів, яких слід переслідувати, його потрібно перезавантажувати кожного разу, коли ви повертаєтесь на екран. Їх фотографії можуть оновлюватися ... ви не хочете бачити фотографії з 5 років тому ...

viewDidLoad: Яку б обробку у вас не було, її потрібно зробити один раз.
viewWilLAppear:Незалежно від обробки, яка потребує змін кожного разу при завантаженні сторінки.

Мітки, піктограми, заголовки кнопок або більшість данихInputedByDeveloper зазвичай не змінюються. Імена, фотографії, посилання, статус кнопок, списки (масиви введення для таблиці TableViews або collectionView) або більшість данихInputedByUser зазвичай змінюються.


Фіолетовий буде називатися у viewDidAppear not the viewWillAppear
Алекс Корнхаузер

@AlexKornhauser, що означає, що це буде називатися? Я кажу, що viewWillAppearви можете запитувати та перевіряти пізні твіти. viewDidAppearзанадто пізно для цього
Мед
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.