viewWillDisappear в iOS — суть методу та як правильно використовувати

Автор: IT Sectr Опубліковано: 2026-03-05 Час читання: 8 хв

viewWillDisappear — це метод UIViewController, який UIKit викликає безпосередньо перед тим, як екран починає зникати з дисплея користувача. Згідно з Apple Developer Documentation, цей метод отримує параметр animated і спрацьовує при push, pop, present, dismiss та перемиканні вкладок. viewWillDisappear — основне місце для збереження стану та коректного очищення ресурсів.

Головне

  • viewWillDisappear викликається перед кожним зникненням екрану
  • Використовується для збереження стану чорновиків та тимчасових даних
  • Відписка від NotificationCenter та KVO — обов’язкове завдання в цьому методі
  • Метод може бути викликаний при скасованому жесті — дублюйте дані в viewDidDisappear
  • super.viewWillDisappear обов’язковий для коректної навігації

Що таке viewWillDisappear

viewWillDisappear — це метод UIViewController, який UIKit викликає безпосередньо перед тим, як View контролера починає зникати з екрану. У цей момент екран ще видний користувачеві, але перехід вже ініційовано: NavigationController почав анімацію push/pop, модальне вікно почало закриватися, або TabBar почав перемикатися на іншу вкладку. Розробник перевизначає цей метод для виконання операцій, які потребують, щоб екран ще був доступний, але вже готується до приховування.

На відміну від viewDidDisappear, який спрацьовує після того, як екран приховано, viewWillDisappear надає останню можливість зберегти дані та звільнити ресурси, поки користувач ще бачить інтерфейс. Це критично важливо для UX — збереження чорновика або зупинка таймера мають відбуватися до того, як користувач перейде на інший екран.

Метод приймає параметр animated, який вказує, чи відбувається зникнення з анімацією. Значення true означає, що UIKit виконує анімований перехід, false — екран зникає миттєво, наприклад при dismiss без анімації або програмному видаленні з ієрархії.

Коли викликається viewWillDisappear

viewWillDisappear викликається в усіх сценаріях, коли поточний екран перестає бути активним. Розглянемо основні випадки, характерні для iOS-розробки.

При push нового екрану

Коли UINavigationController виконує push нового контролера, на поточному викликається viewWillDisappear на початку анімації переходу. У цей момент поточний екран ще видний під новим контролером, що насувається зверху. Це стандартний сценарій, при якому viewWillDisappear спрацьовує з animated = true.

При pop поточного екрану

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

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    saveDraftData()
    NotificationCenter.default.removeObserver(self)
}

При dismiss контролера

При закритті модального вікна viewWillDisappear викликається на закриваному контролері на початку анімації dismiss. У цей момент можна передати результати назад через делегат або замикання, оскільки контролер, який представив модальне вікно, ще не отримав контроль.

При перемиканні вкладок TabBar

UITabBarController викликає viewWillDisappear на контролері вкладки, яку залишають, одразу після того, як користувач торкнув іншої вкладки. Якщо на поточній вкладці є активні процеси — відтворення медіа, завантаження файлу, таймер — їх припиняють або зупиняють тут.

Практичні завдання в viewWillDisappear

viewWillDisappear вирішує конкретні завдання з управління ресурсами та станом. Розглянемо ключові сценарії з прикладами коду.

Збереження користувацьких даних

Найважливіше завдання viewWillDisappear — збереження даних, які користувач ввів або змінив на поточному екрані. Чорновики повідомлень, відредаговані поля форми, вибрані налаштування — усе це має бути збережено до того, як екран зникне. Використовуйте Core Data, UserDefaults або файлове сховище для персистентності.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    guard hasUnsavedChanges else { return }
    draftStorage.save(currentDraft)
}

Відписка від сповіщень

NotificationCenter, KVO та Combine паблішери, на які ви підписались у viewWillAppear або viewDidLoad, мають бути скасовані в viewWillDisappear. Якщо цього не зробити, сповіщення будуть надходити на прихований екран, спричиняючи оновлення інтерфейсу, які користувач не бачить, або — ще гірше — аварії через доступ до вже деалокованих об’єктів.

Зупинка анімацій та таймерів

Анімації UIView, запущені в viewDidAppear, та таймери, що працюють через Timer або DispatchSource, мають бути зупинені в viewWillDisappear. Продовжування анімацій на прихованому екрані витрачає GPU та батарею без будь-якої користі для користувача. Зупиняйте їх явно, викликаючи invalidate у таймерів та removeAllAnimations у шарів.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    countdownTimer?.invalidate()
    countdownTimer = nil
    loadingIndicator.layer.removeAllAnimations()
}

Передача даних назад

Якщо контролер відкривався для отримання результату — вибір елемента, введення тексту, підтвердження дії — viewWillDisappear останній момент, коли оригінальний контролер ще існує в стеку та може приймати дані. Викликайте делегат або замикання до того, як спрацює deinit.

Стратегія збереження стану

Надійне збереження стану екрану — одне з найскладніших завдань в iOS-розробці. viewWillDisappear — важливий, але не єдиний елемент стратегії. Розглянемо комплексний підхід.

Рівень 1 — збереження в viewWillDisappear. Швидке збереження легких даних, які мають бути доступні одразу після повернення. Підходить для UI-стану: позиція прокрутки, вибраний сегмент, текст у полях вводу. Проблема: при скасованому інтерактивному pop-жесті збереження відбувається, хоча користувач залишився на екрані — дані перезаписуються без потреби.

Рівень 2 — збереження в viewDidDisappear. Дублює збереження з першого рівня, але спрацьовує тільки після того, як екран гарантовано приховано. Це страховка від скасованих жестів. Однак якщо ви вже відписалися від сповіщень в viewWillDisappear, viewDidDisappear може не мати доступу до деяких даних.

Рівень 3 — збереження через сповіщення додатка. UIApplication.willResignActiveNotification та UIApplication.didEnterBackgroundNotification перехоплюють згортання додатка. Якщо користувач згорнув додаток, viewWillDisappear міг не викликатися — але збереження через ці сповіщення гарантує цілісність даних при завершенні сесії.

РівеньМетод/СповіщенняНадійністьВикористання
1viewWillDisappearВисокаUI-стан, чорновики
2viewDidDisappearДуже високаКритичні дані
3willResignActiveМаксимальнаПри згортанні

Рекомендація: використовуйте комбінацію всіх трьох рівнів для критичних користувацьких даних. Для некритичного стану достатньо першого рівня. Важливо не перезберігати ті самі дані багаторазово — використовуйте прапорець dirty, що вказує, що дані змінилися з останнього збереження.

Особливу увагу варто приділити стратегії для CRUD-екранів, де користувач вводить дані. На таких екранах не рекомендується зберігати кожен натиск клавіші в viewWillDisappear — це надлишок. Використовуйте автозбереження з затримкою (debounce) через Timer, а viewWillDisappear застосовуйте лише для фінального форсованого збереження, якщо є незбережені зміни. Такий підхід балансує продуктивність та цілісність даних.

Для додатків, що використовують Core Data, додатковим заходом є виклик saveContext в viewWillDisappear лише при наявності реальних змін в managed object context. Перевірка context.hasChanges перед збереженням запобігає зайвим записам до постійного сховища та продовжує термін служби батареї пристрою. Комбінуйте цю перевірку з глобальним збереженням в applicationDidEnterBackground.

Типові помилки в viewWillDisappear

Неправильне використання viewWillDisappear може призвести до втрати даних, витоків пам’яті та нестабільної поведінки додатка. Розглянемо часті помилки iOS-розробників.

Перша помилка — збереження даних лише в viewWillDisappear. Як обговорювалося вище, при інтерактивному pop-жесті метод викликається, навіть якщо екран не зникла насправді. Якщо збереження має побічні ефекти — відправка даних на сервер, зміна стану — це може призвести до хибних спрацьовувань. Додайте перевірку isBeingDismissed або isMovingFromParent.

Друга помилка — відсутність відписки від NotificationCenter. Це один з найчастіших витоків пам’яті в iOS. Якщо ви підписалися в viewWillAppear на UIResponder.keyboardWillShowNotification, але не відписалися в viewWillDisappear, замикання продовжує викликатися. При deinit контролера замикання посилатиметься на вже деалокований об’єкт — аварія додатка гарантована.

Третя помилка — виконання важких синхронних операцій. Збереження великого обсягу даних, запис в Core Data або файлову систему в viewWillDisappear блокує main thread. Якщо операція триває довше, ніж анімація переходу, UIKit призупиняє потік і інтерфейс зависає. Виносьте важкі збереження в фонові черги.

Четверта помилка — забули викликати super. Невиклик super.viewWillDisappear може порушити роботу UINavigationController та UITabBarController, які використовують цей метод для своїх внутрішніх станів. Завжди викликайте super першим або останнім, дотримуючись документації Apple.

Ця проблема погіршується на iOS з активною багатозадачністю та перемиканнями між додатками. П’ята помилка — використання DispatchQueue.main.async після збереження в viewWillDisappear. Якщо ви асинхронно відправляєте блок у головну чергу після виклику super.viewWillDisappear, немає гарантії, що контролер ще існує на момент виконання блока. Завжди використовуйте слабкі посилання [weak self] всередині замикань для запобігання доступу до деалокованої пам’яті та аварій додатка.

Часто задавані питання

Чим відрізняється viewWillDisappear від viewDidDisappear?

viewWillDisappear викликається на початку зникнення, коли екран ще видний. viewDidDisappear — після того, як екран повністю приховано та анімація завершена.

Що робити при скасованому pop-жесті?

Використовуйте viewDidDisappear для підтвердження збереження або перевіряйте властивості isMovingFromParent та isBeingDismissed всередині viewWillDisappear, щоб визначити, чи зникне екран насправді.

Чи потрібно відписуватися від NotificationCenter вручну?

Так, обов’язково, якщо ви використовуєте блоки або селектори з self. ARC не керує підписками на NotificationCenter. В iOS 9+ для блоків використовуйте слабке посилання та відписуйтесь в viewWillDisappear.

Як зберегти дані при force quit через viewWillDisappear?

Ніяк — force quit не викликає методи Lifecycle. Для гарантованого збереження при завершенні додатка використовуйте UIApplication.willTerminateNotification або зберігайте дані в реальному часі в міру їх зміни.

Чи може viewWillDisappear викликатися, коли контролер не зникає?

Так, при інтерактивному pop-жесті UIKit викликає viewWillDisappear одразу після початку жесту. Якщо користувач скасовує жест, екран залишається видним, але метод вже спрацював. Завжди перевіряйте isMovingFromParent.

Підсумки

  • viewWillDisappear викликається перед кожним зникненням екрану — при push, pop, present та dismiss
  • Основне призначення — збереження стану, відписка від сповіщень та зупинка анімацій
  • При інтерактивних жестах метод може бути викликаний без фактичного приховування екрану
  • Використовуйте трьохрівневу стратегію збереження для критичних користувацьких даних
  • Відписка від NotificationCenter в viewWillDisappear запобігає витокам пам’яті
  • Важкі синхронні операції блокують main thread — виносьте їх у фонові черги
  • Завжди викликайте super.viewWillDisappear для підтримки коректної навігації

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також