viewWillAppear — це метод UIViewController, який UIKit викликає щоразу перед тим, як екран стає видимим для користувача. Згідно з Apple Developer Documentation, цей метод отримує булевий параметр animated, який вказує, чи відбувається перехід з анімацією. viewWillAppear — основне місце для оновлення даних та синхронізації стану екрана.
Головне
viewWillAppear — це метод UIViewController, який UIKit викликає безпосередньо перед додаванням View в ієрархію вікон. У цей момент View вже має фінальні розміри після проходів Auto Layout, але ще не видимий користувачу — анімація переходу або не розпочалась, або виконується. Розробник перевизначає цей метод для виконання операцій, які повинні відбутися перед кожним показом екрана.
На відміну від viewDidLoad, який спрацьовує лише один раз, viewWillAppear викликається щоразу, коли екран збирається з'явитися: при стартовому відкритті, при поверненні з дочірнього контролера, після закриття модального вікна та при перемиканні вкладок TabBar. Це робить його ключовим методом для підтримки актуального стану інтерфейсу.
Метод приймає параметр animated типу Bool, який дорівнює true, якщо поява екрана супроводжується анімацією. Цей параметр зручно передавати в методи NavigationBar та TabBar, які також мають аналогічний параметр для узгодженої поведінки.
Час виклику viewWillAppear залежить від типу навігації, але загальне правило незмінне: метод спрацьовує перед тим, як View стає видимим. Розглянемо основні сценарії.
Після виклику viewDidLoad UIKit починає підготовку до показу: View додається в ієрархію, запускаються проходи layout, і безпосередньо перед початком анімації переходу викликається viewWillAppear. У цей момент екран ще не видимий, але всі subviews мають коректні розміри, і можна безпечно оновлювати їхній вміст.
Коли користувач натискає кнопку назад або програмно викликає popViewController, UIKit повертається на попередній екран і викликає у нього viewWillAppear. Це основний сценарій, для якого використовують viewWillAppear — оновлення списку після додавання елемента або синхронізація налаштувань.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
Після закриття модально представленого контролера UIKit викликає viewWillAppear у контролера, який його представив. Цей сценарій потребує особливої уваги, якщо ви використовуєте делегати або замикання для передачі даних назад — viewWillAppear гарантує, що екран оновиться після отримання результату.
TabBarController викликає viewWillAppear у контролера вибраної вкладки щоразу при перемиканні. Якщо на вкладці відображаються динамічні дані — курс валют, сповіщення, статус користувача — viewWillAppear ідеальне місце для їх оновлення.
viewWillAppear вирішує кілька конкретних завдань, які неможливо або неоптимально виконувати в інших методах. Розглянемо основні з них.
Найчастіше застосування viewWillAppear — перезавантаження UITableView або UICollectionView при кожній появі екрана. Якщо дані могли змінитися на попередньому екрані (додавання елемента, зміна статусу), виклик reloadData у viewWillAppear гарантує, що користувач бачить актуальну інформацію.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
У viewWillAppear зручно налаштовувати зовнішній вигляд NavigationBar: приховувати або показувати його, змінювати колір, встановлювати large title. Якщо на різних екранах NavigationBar виглядає по-різному, viewWillAppear — правильне місце для цих змін, оскільки viewDidLoad викликається лише один раз.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
Сповіщення, які мають сенс лише коли екран видимий — клавіатурні, сповіщення про зміну вмісту — підписують у viewWillAppear та відписують у viewDidDisappear. Це запобігає зайвим обробникам, коли екран не активний, та захищає від витоків пам'яті.
Якщо екран може бути прихованим додатком або згорнутим, viewWillAppear — зручне місце для відновлення стану UI: перемикання сегментів, відновлення позиції скролу, скидання тимчасових змін. Користувач отримує екран у передбачуваному вигляді при кожній появі.
На екранах, що відображають лічильники непрочитаних повідомлень, оцінок або сповіщень, viewWillAppear — правильне місце для їх оновлення. Якщо користувач міг змінити кількість на іншому екрані, тут викликають перерахунок та оновлення UITabBarItem.badgeValue або кастомних індикаторів. Це гарантує, що користувач завжди бачить актуальні числа незалежно від того, як довго він перебував на інших екранах.
Окремо варто відзначити роботу з collectionView: якщо дані на екрані представлені у вигляді сітки з комірками, що містять лічильники або статуси, їх оновлення у viewWillAppear має бути вибірковим. Замість повного reloadData використовуйте reloadItemsAtIndexPaths для видимих комірок, щоб уникнути мерехтіння та втрати позиції скролу.
Розуміння різниці між viewWillAppear та viewDidLoad — основа правильної архітектури UIViewController. Ці методи мають різну частоту виклику, різний контекст та різне призначення.
viewDidLoad викликається один раз і підходить для налаштування, яке не змінюється з часом: реєстрація комірок, встановлення делегатів, ініціалізація констант. viewWillAppear викликається при кожній появі та підходить для операцій, які повинні повторюватися: оновлення даних, налаштування видимих елементів, синхронізація стану.
| Характеристика | viewDidLoad | viewWillAppear |
|---|---|---|
| Частота | Один раз | Щоразу при появі |
| View видимий | Ні | Ні (скоро стане видимим) |
| Розміри View | Не фінальні | Фінальні |
| Підходить для | Одноразового налаштування | Оновлення та синхронізації |
| Анімація | Не застосовно | Параметр animated |
Золоте правило: якщо операція повинна виконатися лише один раз — кладіть у viewDidLoad. Якщо щоразу при поверненні на екран — кладіть у viewWillAppear.
Неправильне використання viewWillAppear може призвести до проблем з продуктивністю, надлишкових оновлень та неконсистентного стану інтерфейсу. Розглянемо найпоширеніші помилки.
Перша помилка — дублювання логіки з viewDidLoad. Якщо ви реєструєте комірки таблиці і в viewDidLoad, і в viewWillAppear — реєстрація виконуватиметься багаторазово, хоча достатньо одноразового налаштування. Перемістіть всі одноразові конфігурації в viewDidLoad.
Друга помилка — безумовний reloadData при кожній появі. Якщо дані не змінювалися, перезавантаження таблиці викликає зайві запити до data source та перемальовування комірок, знижуючи продуктивність. Перевіряйте, чи дійсно стан змінився, перед викликом reloadData.
Третя помилка — робота з мережевими запитами без урахування, що екран може бути знову прихований до завершення запиту. Якщо у viewWillAppear ви запускаєте URLSession-запит, а користувач одразу йде на інший екран, результат може бути застосований до вже прихованого View. Використовуйте скасовувані завдання або перевіряйте isViewLoaded та window перед оновленням.
Четверта помилка — забули викликати super. Невклик super.viewWillAppear може порушити роботу батьківських контролерів (UINavigationController, UITabBarController) та призвести до некоректної обробки жестів і переходів. super повинен бути викликаний завжди.
П'ята помилка — зміна констрейнтів без виклику layoutIfNeeded. Якщо у viewWillAppear ви програмно змінюєте constraints, UIKit не застосовує їх миттєво — зміни накопичуються до наступного проходу layout. Для негайного застосування змін після модифікації констрейнтів викликайте view.layoutIfNeeded(). Це особливо важливо при налаштуванні висоти елементів, що залежать від вмісту.
Шоста помилка — спроба виконати анімацію у viewWillAppear. Як згадувалося вище, UIKit ще обробляє перехідну анімацію, і ваша анімація може конкурувати з системною. Якщо вам потрібно, щоб елемент з'явився з ефектом, використовуйте вхідну анімацію у viewDidAppear, а у viewWillAppear лише налаштуйте початковий стан: прозорість 0, transform у масштабі 0.8 тощо.
Сьома помилка — ігнорування параметра animated. Деякі розробники не перевіряють значення animated у viewWillAppear та виконують операції, які повинні залежати від наявності анімації. Наприклад, приховування NavigationBar при animated = false можна зробити без анімації, а при animated = true — з анімацією, щоб перехід виглядав плавно. Завжди передавайте параметр animated у відповідні методи UIKit.
Восьма помилка — модифікація UI при невидимому екрані. Якщо у viewWillAppear ви запускаєте мережевий запит, а його completion block оновлює UI, коли екран міг уже зникнути, користувач побачить мерехтіння або неконсистентний стан. Завжди перевіряйте isViewLoaded та window перед оновленням UI в замиканнях. Ця проста дія запобігає крашам та зайвим перемальовуванням інтерфейсу.
Часті запитання
viewWillAppear викликається до початку анімації появи, коли View ще не видимий. viewDidAppear — після завершення анімації, коли екран повністю відобразився та доступний для взаємодії.
У нормальних умовах viewWillAppear викликається завжди при появі екрана. Виняток — force quit додатку, при якому UIKit не встигає викликати методи життєвого циклу.
Так, обов'язково. UIKit використовує цей виклик для внутрішньої координації з UINavigationController та UITabBarController. Без super можуть зламатися жести та анімації переходів.
При кожному перемиканні на вкладку. UIKit викликає viewWillAppear у контролера вибраної вкладки одразу після того, як користувач торкається відповідної іконки в TabBar.
Використовуйте властивості контролера або спільне джерело даних. Перед викликом popViewController встановіть потрібні значення на попередньому контролері, і в його viewWillAppear вони вже будуть доступні.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також