viewDidDisappear: podstata metody, životní cyklus UIViewController a kdy se volá

Autor: IT Sectr Publikováno: 2026-03-05 Doba čtení: 9 min

viewDidDisappear — je metoda životního cyklu UIViewController, která je volána ihned po úplném zmizení pohledu (view) z obrazovky zařízení iOS. Vývojáři ji používají k zastavení animací, uvolnění operační paměti, odhlášení odběru oznámení a ukládání aktuálního stavu. Podle Apple Developer Documentation (2025) správná implementace této metody zabraňuje až 40% únikům paměti v aplikacích s aktivní navigací. Bez ní mohou procesy na pozadí nadále běžet, spotřebovávat zdroje baterie a procesoru. Správné použití viewDidDisappear je jednou z klíčových dovedností iOS vývojáře, která přímo ovlivňuje výkon a stabilitu aplikace.

Hlavní body

  • viewDidDisappear — konečná metoda životního cyklu, volaná po zmizení pohledu z obrazovky
  • Používá se pro uvolnění prostředků: zastavení časovačů, skrytí indikátorů načítání
  • Povinná pro odhlášení odběru z NotificationCenter a pozorování KVO, aby se předešlo únikům
  • Liší se od viewWillDisappear tím, že je volána po dokončení animace přechodu
  • Nenahrazuje deinit — deinit je odpovědný za konečné zničení objektu

Co je viewDidDisappear?

viewDidDisappear — je metoda háku nadřízené třídy UIViewController, kterou systém volá poté, co byl pohled (view) zcela odstraněn z hierarchie oken na obrazovce. Je součástí standardního životního cyklu pohledu v UIKit a poskytuje vývojáři bod pro provádění dokončovacích operací.

Metoda je deklarována v protokolu UIViewController a je k dispozici pro přepsání ve všech podtřídách. Signatura metody: override func viewDidDisappear(_ animated: Bool). Parametr animated udává, zda byl přechod doprovázen animací. To umožňuje rozlišit programové a animované přechody pro přesnější řízení chování.

Na rozdíl od viewWillDisappear, který je volán před začátkem animace, viewDidDisappear zaručuje, že pohled již není pro uživatele viditelný. To je kritické pro operace, které musí být provedeny až po úplném skrytí rozhraní — například skrytí prvků překrytí na celou obrazovku nebo dokončení nahrávání videa.

Signatura a deklarace

Metoda je definována v základní třídě UIViewController a má následující signaturu:

swift
import UIKit

class MyViewController: UIViewController {
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // Uvolnění prostředků a odhlášení odběru
    }
}

Povinné volání super.viewDidDisappear(animated) v prvním řádku implementace — to je požadavek UIKit. Bez něj nemůže nadřízená třída správně dokončit interní procesy související se zobrazením pohledu. Ignorování tohoto pravidla vede k nepředvídatelnému chování navigace a potenciálním pádům.

Místo viewDidDisappear v životním cyklu UIViewController

Plný životní cyklus UIViewController se skládá ze šesti klíčových metod, z nichž každá odpovídá za určitou fázi existence pohledu. viewDidDisappear dokončuje sekvenci skrytí, následující po viewWillDisappear. Je důležité porozumět pořadí volání všech metod pro správné rozdělení inicializace a uvolňování prostředků.

Pořadí při objevení pohledu: viewDidLoadviewWillAppearviewDidAppear. Při skrytí: viewWillDisappearviewDidDisappear. Závěrečná fáze — deinit, který je volán při zničení objektu UIViewController. Těchto šest metod tvoří úplný cyklus, zaručující předvídatelné řízení stavu.

MetodaOkamžik voláníTypické použití
viewDidLoadPo načtení pohledu do pamětiPočáteční nastavení UI, přihlášení k datům
viewWillAppearPřed objevením pohledu na obrazovceAktualizace dat před zobrazením
viewDidAppearPo objevení pohledu na obrazovceSpuštění animací, zahájení animace
viewWillDisappearPřed zmizením pohleduUložení vstupních dat, zrušení operací
viewDidDisappearPo zmizení pohleduUvolnění prostředků, odhlášení odběru oznámení
deinitPři zničení objektuKonečné čištění, uvolnění silných referencí

Každá z těchto metod je volána přesně jednou pro odpovídající přechod. Výjimka — viewDidLoad, který může být znovu volán, pokud byl ViewController uvolněn z paměti kvůli nedostatku prostředků a poté obnoven. V takovém případě bude viewDidDisappear předcházet novému viewDidLoad.

Souvislost s animací přechodu

Parametr animated v signatuře metody udává, zda byl přechod animovaný. To je užitečné pro rozlišení programových přechodů bez animace (například při nastavení rootViewController) a animovaných přechodů iniciovaných uživatelem. Pokud je hodnota false, je možné, že byl ovladač násilně skryt systémem — v takovém případě mohou být některé časově závislé operace irelevantní.

Kdy se volá viewDidDisappear

Systém volá viewDidDisappear přesně ve dvou scénářích: když je ViewController odstraněn ze zásobníku navigace a když je překryt jiným ovladačem. V obou případech metoda signalizuje, že pohled již není pro uživatele viditelný, a vývojář by měl uvolnit prostředky, které nejsou potřeba na pozadí. Porozumění těmto scénářům zabraňuje chybným předpokladům o stavu aplikace.

První scénář — pop z UINavigationController. Když uživatel stiskne tlačítko „Zpět”, volá se popViewController: animated. Aktuální ovladač obdrží viewDidDisappear a poté, pokud na něj již nevedou žádné silné reference, deinit. Druhý scénář — present/dismiss. Při modálním zobrazení nového ovladače obdrží presentingViewController viewDidDisappear. Při dismiss je tato metoda volána u ovladače, který byl zobrazen modálně.

Třetí, méně zřejmý scénář — přidání child ViewController. Pokud je do kontejnerového ovladače (například UIPageViewController nebo UITabBarController) přidán nový podřízený ovladač, aktivní podřízený ovladač obdrží viewDidDisappear. To je kritické pro aplikace s kartami nebo karusely stránek — každá změna karty by měla správně pozastavit činnost neaktivní obrazovky.

Výjimky a ne zřejmé případy

Existuje důležitá výjimka: pokud je UIViewController zobrazen v modálním okně a uživatel jej interaktivně zavře přejetím dolů, systém nemusí volat viewDidDisappear při neúplném přejetí. Toto chování se objevilo v iOS 13 spolu s interaktivním dismiss. Vývojáři by měli spravovat stav prostřednictvím UIAdaptivePresentationControllerDelegate a metody didDismiss pro zaručené přijetí události.

Další vlastnost — varování o paměti. Při nedostatku paměti může systém uvolnit pohled ovladače, který není zobrazen na obrazovce. V tomto případě je viewDidDisappear obvykle volán před uvolněním, ale vývojář by měl pro jistotu duplikovat kriticky důležité operace uvolnění v didReceiveMemoryWarning. Takový přístup zabraňuje ztrátě dat v extrémních scénářích.

Typické scénáře použití

viewDidDisappear se používá pro tři hlavní kategorie operací: zastavení aktivit, uvolnění prostředků a uložení stavu. Každá kategorie má své vlastní osvědčené postupy vytvořené komunitou iOS vývojářů. Podívejme se na nejčastější scénáře s příklady implementace.

  • Zastavení animací — volání layer.removeAllAnimations() pro CALayer, zastavení bloků UIView.animate
  • Uvolnění prostředků — vynulování velkých obrázků, resetování dat v mezipaměti, zavření deskriptorů souborů
  • Odhlášení odběru oznámení — odstranění pozorovatelů z NotificationCenter.default, zastavení pozorování KVO
  • Uložení průběhu — zápis konceptů do CoreData nebo UserDefaults při zavření editační obrazovky
  • Skrytí překrytí — odstranění indikátorů načítání, nápověd a prvků popover, které by neměly zůstat po přechodu

Příklad: odhlášení odběru z NotificationCenter

Typická chyba — přihlásit se k oznámením v viewDidLoad a nikdy se neodhlásit. To vede k volání handleru na zničeném objektu, což způsobí pád. Správný přístup — přihlášení v viewWillAppear a odhlášení v viewDidDisappear, což zaručuje aktuálnost přihlášení pouze během zobrazení ovladače na obrazovce.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleKeyboardShow),
        name: UIResponder.keyboardWillShowNotification,
        object: nil
    )
}

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

Tento vzor zaručuje, že handler oznámení je aktivní pouze tehdy, když je ovladač viditelný na obrazovce. Při přechodu na jinou obrazovku jsou všechna přihlášení automaticky odstraněna a při návratu obnovena. To zvyšuje spolehlivost aplikace a eliminuje třídu chyb souvisejících s oznámeními.

Příklady kódu ve Swift

Podívejme se na dva praktické příklady použití viewDidDisappear v reálných projektech. První příklad demonstruje zastavení časovače při skrytí obrazovky, druhý — správné ukončení pozorování klávesnice. Oba příklady následují princip uvolňování prostředků při neaktivitě ovladače.

Zastavení časovače

Pokud na obrazovce běží Timer pro aktualizaci UI (například odpočítávání nebo karusel), musí být zastaven při skrytí ovladače. Pokračování činnosti časovače na pozadí nejen spotřebovává zdroje procesoru, ale může také způsobit výjimku při pokusu o aktualizaci neviditelného UI.

swift
class CountdownViewController: UIViewController {
    private var countdownTimer: Timer?
    private var remainingSeconds: Int = 60

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        startTimer()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        invalidateTimer()
    }

    private func invalidateTimer() {
        countdownTimer()?.invalidate()
        countdownTimer = nil
    }
}

Pozastavení videa při skrytí

V mnoha aplikacích přehrává AVPlayer video ve vestavěném přehrávači. Pokud uživatel přejde na jinou obrazovku, video by se mělo automaticky pozastavit. Implementace v viewDidDisappear zaručuje, že k pozastavení dojde po úplném skrytí obrazovky — to zabraňuje blikání černého snímku při přechodu.

swift
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if player().timeControlStatus == .playing {
        player().pause()
        playerLayer().removeFromSuperlayer()
    }
    player = nil
}

Vynulování proměnné player po pozastavení navíc uvolní paměť obsazenou vyrovnávacími paměťmi videa. Tento přístup je obzvláště důležitý pro aplikace s dlouhými videi, kde může vyrovnávací paměť zabírat desítky megabajtů. Kombinace pozastavení s vynulováním referencí minimalizuje stopu aplikace na pozadí.

viewDidDisappear a další metody životního cyklu

viewDidDisappear je často zaměňován s viewWillDisappear a deinit, avšak každá z těchto metod má svou vlastní oblast odpovědnosti. Porozumění hranicím mezi nimi je klíčem ke stabilní architektuře iOS aplikace. Nesprávné použití může vést k dvojímu uvolnění prostředků nebo naopak k jejich úniku.

Hlavní rozdíl viewDidDisappear od viewWillDisappear — okamžik volání. viewWillDisappear je volán, když je pohled ještě viditelný, ale již se připravuje na zmizení. To je vhodné pro ukládání viditelných dat (text v polích pro zadávání). viewDidDisappear je volán po dokončení animace, když je pohled zaručeně neviditelný — ideální pro uvolnění prostředků nesouvisejících s vizuálním stavem.

deinit, na rozdíl od viewDidDisappear, je volán pouze při zničení objektu UIViewController v paměti. Pokud je ovladač pouze skryt (například překryt modálním oknem), deinit není volán. V této situaci je viewDidDisappear jediným bodem pro provádění dokončovacích operací. K úplnému uvolnění prostředků by mělo dojít v deinit, ale viewDidDisappear je odpovědný za dočasné uvolnění do opětovného objevení.

Kdy použít kterou metodu

  • viewWillDisappear — uložení vstupních dat, odeslání analýzy o zahájení přechodu
  • viewDidDisappear — zastavení animací, odhlášení odběru oznámení, skrytí prvků překrytí
  • deinit — konečné uvolnění velkých prostředků, uzavření síťových připojení

Při vývoji s SwiftUI se metoda viewDidDisappear nepoužívá — nahrazuje ji modifikátor .onDisappear, který funguje podobným způsobem. Ve SwiftUI však neexistuje přímá kontrola nad životním cyklem a vývojáři se spoléhají na Combine a State objekty pro správu prostředků. Pro UIKit aplikace zůstává viewDidDisappear hlavním nástrojem pro správu skrytí obrazovky.

Typické chyby při implementaci

Dokonce i zkušení iOS vývojáři dělají chyby při práci s viewDidDisappear. Podívejme se na pět nejčastějších problémů a způsoby, jak jim předcházet. Znalost těchto anti-vzorů pomáhá vyhnout se obtížně dohledatelným chybám souvisejícím s životním cyklem ovladačů.

  • Vynechání super.viewDidDisappear — volání super je povinné pro správnou funkci UIKit, jeho absence může způsobit narušení vnitřního stavu ovladače
  • Těžké operace v viewDidDisappear — synchronní zápis velkých dat v viewDidDisappear blokuje hlavní vlákno a zhoršuje animaci přechodu
  • Zapomenuté odhlášení odběru oznámení — pokud removeObserver není volán v viewDidDisappear, handler se může aktivovat na zombie objektu, což způsobí EXC_BAD_ACCESS
  • Dvojí odhlášení odběru — odstranění pozorovatele, který již byl odstraněn na jiném místě, vede k výjimce NSInternalInconsistencyException
  • Závislost na pořadí volání — ve vnořených kontejnerech není pořadí volání viewDidDisappear u podřízených a nadřízených ovladačů zaručeno

Zvláštní pozornost vyžaduje bezpečnost vláken. Pokud je viewDidDisappear volán na hlavním vlákně (což UIKit zaručuje), ale uvolňování prostředků zahrnuje asynchronní operace, je třeba synchronizovat přístup ke sdíleným datům. Použití DispatchQueue.main.async uvnitř viewDidDisappear pro aktualizaci UI po dokončení asynchronního úkolu — běžný, ale správný přístup.

Další důležitý anti-vzor — volání delegátských metod uvnitř viewDidDisappear, které mohou iniciovat nový přechod nebo modální zobrazení. To vytváří cyklus, ve kterém může být viewDidDisappear znovu volán před dokončením prvního volání. Apple doporučuje vyhýbat se modálním zobrazením uvnitř metod životního cyklu a přesunout je do samostatných obsluh událostí.

Často kladené otázky

Čím se liší viewDidDisappear od viewWillDisappear?

viewWillDisappear je volán před začátkem animace skrytí, když je pohled ještě viditelný. viewDidDisappear — po úplném zmizení pohledu. Pro ukládání dat použijte viewWillDisappear, pro uvolňování prostředků — viewDidDisappear.

Je nutné volat super.viewDidDisappear?

Ano, volání super.viewDidDisappear(animated) je povinné. UIKit používá tuto metodu pro interní oznámení a dokončení stavu přechodu. Bez volání super jsou možné pády v UINavigationController a UITabBarController.

Může se viewDidDisappear nevolat?

Ano, při interaktivním dismiss v iOS 13+ (přejetí dolů) se metoda nemusí volat, pokud gesto není dokončeno. Pro zaručené přijetí události použijte delegáta UIAdaptivePresentationControllerDelegate a metodu presentationControllerDidDismiss.

Co je lepší: viewDidDisappear nebo deinit?

deinit je volán pouze při zničení objektu, zatímco viewDidDisappear je volán při každém skrytí. Pro uvolňování prostředků při každém přechodu (například odhlášení odběru oznámení) použijte viewDidDisappear. Pro konečné čištění při odstranění ovladače — deinit.

Jak funguje viewDidDisappear ve SwiftUI?

Ve SwiftUI se místo viewDidDisappear používá modifikátor .onDisappear { }. Ten je volán při skrytí pohledu z hierarchie. Na rozdíl od UIKit, SwiftUI nezaručuje volání onDisappear ve všech scénářích během animací.

Shrnutí

  • viewDidDisappear — poslední metoda životního cyklu před skrytím, volaná po dokončení animace přechodu
  • Hlavní účel — uvolnění prostředků, zastavení časovačů a odhlášení odběru oznámení
  • Povinné volání super.viewDidDisappear pro správnou funkci UIKit
  • Liší se od viewWillDisappear okamžikem volání: po animaci, ne před ní
  • Nenahrazuje deinit — deinit je volán při zničení objektu, viewDidDisappear při každém skrytí
  • Nepoužívá se pro těžké synchronní operace — ty blokují hlavní vlákno a narušují animaci
  • V iOS 13+ je vyžadováno dodatečné zpracování prostřednictvím UIAdaptivePresentationControllerDelegate pro zaručené volání

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také