viewDidDisappear — är en livscykelmetod för UIViewController som anropas omedelbart efter att vyn (view) helt har försvunnit från skärmen på en iOS-enhet. Utvecklare använder den för att stoppa animationer, frigöra RAM-minne, avsluta prenumerationer på notifikationer och spara det aktuella tillståndet. Enligt Apple Developer Documentation (2025) förhindrar korrekt implementering av denna metod upp till 40% av minnesläckor i applikationer med aktiv navigering. Utan den kan bakgrundsprocesser fortsätta att köras och förbruka batteri- och processorresurser. Korrekt användning av viewDidDisappear är en av nyckelfärdigheterna för en iOS-utvecklare som direkt påverkar applikationens prestanda och stabilitet.
Huvudpunkter
viewDidDisappear — är en hook-metod för superklassen UIViewController som systemet anropar efter att vyn (view) har tagits bort helt från fönsterhierarkin på skärmen. Den är en del av den standardiserade livscykeln för en vy i UIKit och ger utvecklaren en punkt för att utföra avslutande operationer.
Metoden är deklarerad i UIViewController-protokollet och är tillgänglig för överskuggning i alla underklasser. Metodens signatur: override func viewDidDisappear(_ animated: Bool). Parametern animated anger om övergången åtföljdes av en animation. Detta gör det möjligt att skilja mellan programmatiska och animerade övergångar för mer exakt kontroll av beteendet.
Till skillnad från viewWillDisappear, som anropas innan animationen startar, garanterar viewDidDisappear att vyn inte längre är synlig för användaren. Detta är kritiskt för operationer som endast ska utföras efter att gränssnittet har dolts helt — till exempel att dölja overlay-element i helskärm eller slutföra videoinspelning.
Metoden definieras i basklassen UIViewController och har följande signatur:
import UIKit
class MyViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Frigöra resurser och avsluta prenumeration
}
}
Det obligatoriska anropet av super.viewDidDisappear(animated) i den första raden av implementeringen — detta är ett krav från UIKit. Utan det kan superklassen inte korrekt slutföra interna processer relaterade till visningen av vyn. Att ignorera denna regel leder till oförutsägbart navigeringsbeteende och potentiella krascher.
Den fullständiga livscykeln för UIViewController består av sex nyckelmetoder, var och en ansvarig för en specifik fas av vyns existens. viewDidDisappear slutför döljningssekvensen, efter viewWillDisappear. Det är viktigt att förstå anropsordningen för alla metoder för att korrekt fördela initiering och frigöring av resurser.
Ordningen när vyn visas: viewDidLoad → viewWillAppear → viewDidAppear. Vid döljning: viewWillDisappear → viewDidDisappear. Den sista fasen — deinit, som anropas när UIViewController-objektet förstörs. Dessa sex metoder bildar en komplett cykel som garanterar förutsägbar tillståndshantering.
| Metod | Anropstidpunkt | Typisk tillämpning |
|---|---|---|
| viewDidLoad | Efter att vyn har laddats i minnet | Inledande UI-konfiguration, prenumeration på data |
| viewWillAppear | Innan vyn visas på skärmen | Uppdatera data före visning |
| viewDidAppear | Efter att vyn har visats på skärmen | Starta animationer, påbörja animation |
| viewWillDisappear | Innan vyn försvinner | Spara inmatade data, avbryta operationer |
| viewDidDisappear | Efter att vyn har försvunnit | Frigöra resurser, avsluta prenumeration på notifikationer |
| deinit | När objektet förstörs | Slutlig rensning, frigöra starka referenser |
Var och en av dessa metoder anropas exakt en gång för motsvarande övergång. Undantag — viewDidLoad, som kan anropas igen om ViewController har avlastats från minnet på grund av resursbrist och sedan återställts. I sådana fall kommer viewDidDisappear att föregå en ny viewDidLoad.
Parametern animated i metodens signatur anger om övergången var animerad. Detta är användbart för att skilja mellan programmatiska övergångar utan animation (till exempel vid inställning av rootViewController) och animerade övergångar som initierats av användaren. Om värdet är false kan kontrollern ha dolts tvångsmässigt av systemet — i sådana fall kan vissa tidsberoende operationer vara irrelevanta.
Systemet anropar viewDidDisappear i exakt två scenarier: när ViewController tas bort från navigeringsstacken och när den täcks av en annan kontrollern. I båda fallen signalerar metoden att vyn inte längre är synlig för användaren och utvecklaren bör frigöra resurser som inte behövs i bakgrunden. Att förstå dessa scenarier förhindrar felaktiga antaganden om applikationens tillstånd.
Det första scenariot — pop från UINavigationController. När användaren trycker på knappen „Tillbaka” anropas popViewController: animated. Den aktuella kontrollern får viewDidDisappear, och sedan, om det inte finns fler starka referenser till den, deinit. Det andra scenariot — present/dismiss. Vid modal visning av en ny kontrollern får presentingViewController viewDidDisappear. Vid dismiss anropas denna metod på kontrollern som visades modalt.
Det tredje, mindre uppenbara scenariot — lägga till en child ViewController. Om en ny barnkontrollern läggs till i en behållarkontrollern (till exempel UIPageViewController eller UITabBarController), får den aktiva barnkontrollern viewDidDisappear. Detta är kritiskt för applikationer med flikar eller sidkaruseller — varje flikbyte måste korrekt pausa arbetet på den inaktiva skärmen.
Det finns ett viktigt undantag: om UIViewController visas i ett modalt fönster och användaren stänger det interaktivt genom att svepa nedåt, kan systemet underlåta att anropa viewDidDisappear vid ofullständig svepning. Detta beteende uppstod i iOS 13 tillsammans med interaktiv dismiss. Utvecklare måste hantera tillståndet via UIAdaptivePresentationControllerDelegate och metoden didDismiss för garanterad mottagning av händelsen.
En annan funktion — minnesvarningar. Vid minnesbrist kan systemet avlasta vyn för en kontrollern som inte visas på skärmen. I detta fall anropas viewDidDisappear vanligtvis före avlastning, men utvecklaren bör duplicera kritiskt viktiga frigöringsoperationer i didReceiveMemoryWarning för säkerhets skull. Ett sådant tillvägagångssätt förhindrar dataförlust i extrema scenarier.
viewDidDisappear används för tre huvudkategorier av operationer: stoppa aktiviteter, frigöra resurser och spara tillstånd. Varje kategori har sina egna bästa praxis som utvecklats av iOS-utvecklargemenskapen. Låt oss titta på de vanligaste scenarierna med implementeringsexempel.
Ett typiskt misstag — prenumerera på notifikationer i viewDidLoad och aldrig avsluta prenumerationen. Detta leder till att hanteraren anropas på ett förstört objekt, vilket orsakar en krasch. Rätt tillvägagångssätt — prenumerera i viewWillAppear och avsluta prenumerationen i viewDidDisappear, vilket garanterar att prenumerationen endast är aktiv under visning av kontrollern på skärmen.
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)
}
Detta mönster garanterar att notifikationshanteraren endast är aktiv när kontrollern är synlig på skärmen. Vid övergång till en annan skärm tas alla prenumerationer automatiskt bort och vid återkomst återställs de. Detta ökar applikationens pålitlighet och eliminerar en klass av buggar relaterade till notifikationer.
Låt oss titta på två praktiska exempel på användning av viewDidDisappear i verkliga projekt. Det första exemplet visar stopp av en timer vid döljning av skärmen, det andra — korrekt avslutning av tangentbordsövervakning. Båda exemplen följer principen att frigöra resurser när kontrollern är inaktiv.
Om en Timer körs på skärmen för att uppdatera UI (till exempel nedräkning eller karusell), måste den stoppas när kontrollern döljs. Fortsatt körning av timern i bakgrunden förbrukar inte bara processorresurser utan kan också orsaka ett undantag vid försök att uppdatera ett osynligt UI.
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
}
}
I många applikationer spelar AVPlayer upp video i en inbyggd spelare. Om användaren går till en annan skärm bör videon automatiskt pausas. Implementering i viewDidDisappear garanterar att pausen sker efter att skärmen har dolts helt — detta förhindrar att en svart bildruta blinkar vid övergången.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if player().timeControlStatus == .playing {
player().pause()
playerLayer().removeFromSuperlayer()
}
player = nil
}
Att nollställa variabeln player efter pausen frigör dessutom minnet som upptas av videobuffertar. Detta tillvägagångssätt är särskilt viktigt för applikationer med långa videor, där bufferten kan uppta tiotals megabyte. Att kombinera paus med nollställning av referenser minimerar applikationens fotavtryck i bakgrunden.
viewDidDisappear förväxlas ofta med viewWillDisappear och deinit, men var och en av dessa metoder har sitt eget ansvarsområde. Att förstå gränserna mellan dem är nyckeln till en stabil arkitektur för iOS-applikationer. Felaktig användning kan leda till dubbel frigöring av resurser eller, omvänt, till läckage.
Den största skillnaden mellan viewDidDisappear och viewWillDisappear — anropstidpunkten. viewWillDisappear anropas när vyn fortfarande är synlig men redan förbereder sig för att försvinna. Detta är lämpligt för att spara synliga data (text i inmatningsfält). viewDidDisappear anropas efter att animationen har slutförts, när vyn garanterat är osynlig — idealisk för att frigöra resurser som inte är relaterade till visuellt tillstånd.
deinit, till skillnad från viewDidDisappear, anropas endast när UIViewController-objektet förstörs i minnet. Om kontrollern endast är dold (till exempel täckt av ett modalt fönster), anropas inte deinit. I denna situation är viewDidDisappear den enda punkten för att utföra avslutande operationer. Fullständig frigöring av resurser bör ske i deinit, men viewDidDisappear ansvarar för temporär frigöring fram till återuppträdande.
Vid utveckling med SwiftUI används inte metoden viewDidDisappear — den ersätts av modifieraren .onDisappear, som fungerar på liknande sätt. I SwiftUI saknas dock direkt kontroll över livscykeln, och utvecklare förlitar sig på Combine och State-objekt för resurshantering. För UIKit-applikationer förblir viewDidDisappear det huvudsakliga verktyget för hantering av skärmdöljning.
Även erfarna iOS-utvecklare gör misstag i arbetet med viewDidDisappear. Låt oss titta på fem vanliga problem och sätt att förebygga dem. Kännedom om dessa antimönster hjälper till att undvika svårupptäckta buggar relaterade till kontrollerns livscykel.
Särskild uppmärksamhet kräver trådsäkerhet. Om viewDidDisappear anropas på huvudtråden (vilket UIKit garanterar), men frigöring av resurser innefattar asynkrona operationer, måste åtkomst till delade data synkroniseras. Användning av DispatchQueue.main.async inuti viewDidDisappear för att uppdatera UI efter slutförandet av en asynkron uppgift — ett vanligt men korrekt tillvägagångssätt.
Ett annat viktigt antimönster — anrop av delegatmetoder inuti viewDidDisappear som kan initiera en ny övergång eller modal visning. Detta skapar en cykel där viewDidDisappear kan anropas igen innan det första anropet har slutförts. Apple rekommenderar att undvika modala visningar inuti livscykelmetoder och istället flytta dem till separata händelsehanterare.
Vanliga frågor
viewWillDisappear anropas innan döljningsanimationen startar, när vyn fortfarande är synlig. viewDidDisappear — efter att vyn helt har försvunnit. För att spara data använd viewWillDisappear, för att frigöra resurser — viewDidDisappear.
Ja, anrop av super.viewDidDisappear(animated) är obligatoriskt. UIKit använder denna metod för interna notifikationer och slutförande av övergångstillstånd. Utan super-anrop är krascher i UINavigationController och UITabBarController möjliga.
Ja, vid interaktiv dismiss i iOS 13+ (svep nedåt) kan metoden utebli om gesten inte slutförs. För garanterad mottagning av händelsen, använd delegaten UIAdaptivePresentationControllerDelegate och metoden presentationControllerDidDismiss.
deinit anropas endast när objektet förstörs, medan viewDidDisappear anropas vid varje döljning. För att frigöra resurser vid varje övergång (till exempel avsluta prenumeration på notifikationer) använd viewDidDisappear. För slutlig rensning vid borttagning av kontrollern — deinit.
I SwiftUI används istället för viewDidDisappear modifieraren .onDisappear { }. Den anropas när vyn döljs från hierarkin. Till skillnad från UIKit garanterar SwiftUI inte anrop av onDisappear i alla scenarier under animationer.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också