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. В този момент резултатите могат да бъдат върнати обратно чрез делегат или closure, тъй като контролерът, който е представил модалния прозорец, все още не е получил контрол.

При превключване на табове на 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 publisher-и, на които сте се абонирали в viewWillAppear или viewDidLoad, трябва да бъдат отменени в viewWillDisappear. Ако не направите това, известията ще пристигат на скрития екран, причинявайки актуализации на UI, които потребителят не вижда, или по-лошо — сривове поради препратки към вече освободени обекти.

Спиране на анимации и таймери

Анимациите на 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 е последният момент, когато оригиналният контролер все още съществува в стека и може да приеме данни. Извикайте делегата или closure преди да се извика 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 преди запазване предотвратява ненужни записи в persistent store и удължава живота на батерията на устройството. Комбинирайте тази проверка с глобално запазване в applicationDidEnterBackground.

Типични грешки в viewWillDisappear

Неправилното използване на viewWillDisappear може да доведе до загуба на данни, изтичане на памет и нестабилно поведение на приложението. Нека разгледаме честите грешки на iOS разработчиците.

Първа грешка — запазване на данни само в viewWillDisappear. Както беше обсъдено по-горе, при интерактивен pop жест методът се извиква, дори ако екранът не изчезне. Ако запазването има странични ефекти — изпращане на данни към сървър, промяна на състояние — това може да доведе до фалшиви задействания. Добавете проверка на isBeingDismissed или isMovingFromParent.

Втора грешка — липса на отписване от NotificationCenter. Това е едно от най-честите изтичания на памет в iOS. Ако сте се абонирали в viewWillAppear за UIResponder.keyboardWillShowNotification, но не сте се отписали в viewWillDisappear, closure продължава да се извиква. При deinit на контролера, closure ще препраща към освободен обект — срив на приложението е гарантиран.

Трета грешка — изпълнение на тежки синхронни операции. Запазването на голямо количество данни, запис в Core Data или файловата система в viewWillDisappear блокира main thread. Ако операцията продължава по-дълго от анимацията на прехода, UIKit спира нишката и интерфейсът замръзва. Преместете тежките запазвания в опашки на заден план.

Четвърта грешка — забравяте да извикате super. Неизвикването на super.viewWillDisappear може да наруши работата на UINavigationController и UITabBarController, които използват този метод за вътрешните си състояния. Винаги извиквайте super първи или последен, според документацията на Apple.

Този проблем се задълбочава в iOS с активно многозадачност и превключване между приложения. Пета грешка — използване на DispatchQueue.main.async след запазване в viewWillDisappear. Ако асинхронно изпратите блок в главната опашка след извикване на super.viewWillDisappear, няма гаранция, че контролерът все още съществува в момента на изпълнение на блока. Винаги използвайте слаби референции [weak self] вътре в closures, за да предотвратите препратка към освободена памет и да предотвратите срив на приложението.

Често задавани въпроси

Каква е разликата между 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също