viewDidAppear è un metodo di UIViewController che UIKit chiama dopo che lo schermo è completamente apparso sul display e tutte le animazioni di transizione sono terminate. Secondo la Documentazione per Sviluppatori Apple, questo metodo garantisce che la View sia visibile all’utente e pronta per l’interazione. viewDidAppear è il posto ottimale per avviare animazioni, tracciamento e operazioni asincrone.
Punti chiave
viewDidAppear è un metodo di UIViewController che UIKit chiama dopo che la View è stata aggiunta alla gerarchia delle finestre e l’animazione di transizione è stata completata completamente. A questo punto, lo schermo è nel suo stato finale: è visibile, interagibile e tutte le animazioni UIKit si sono fermate. Lo sviluppatore sovrascrive questo metodo per eseguire azioni che richiedono che lo schermo sia garantito davanti agli occhi dell’utente.
A differenza di viewWillAppear, dove lo schermo si sta solo preparando a mostrarsi, viewDidAppear segnala che l’utente vede già l’interfaccia. Questa è una differenza critica: avviare un’animazione in viewWillAppear può causare la perdita di fotogrammi perché UIKit sta ancora elaborando la transizione. In viewDidAppear, la transizione è completa e le risorse del controller possono essere utilizzate per renderizzare nuovi contenuti.
Il metodo accetta un parametro animated di tipo Bool, simile a viewWillAppear. Se è true, l’apparizione dello schermo è stata accompagnata da animazione. Questo parametro può essere utilizzato per adattare il comportamento dell’interfaccia: ad esempio, saltare un’animazione di ingresso durante un ritorno non animato.
viewDidAppear viene chiamato in tutti gli scenari in cui lo schermo ha completato il suo processo di apparizione. Esaminiamo i casi principali dal punto di vista di uno sviluppatore iOS.
Dopo che UINavigationController ha terminato un’animazione push o pop, viewDidAppear viene chiamato sul controller di destinazione. Per il primo schermo nello stack, viene eseguito dopo l’animazione iniziale di apertura. Questo è lo scenario principale, ed è quello a cui gli sviluppatori mirano principalmente quando inseriscono la logica in viewDidAppear.
Quando l’utente chiude un controller presentato modalmente e torna al precedente, UIKit chiama viewDidAppear sul controller di ritorno. Il parametro animated corrisponderà a se il dismiss è stato eseguito con animazione. Questo momento è importante per aggiornare l’interfaccia dopo aver ricevuto dati da uno schermo figlio.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
logScreenView()
startOnboardingAnimation()
}
UITabBarController chiama viewDidAppear sul controller della scheda selezionata dopo aver completato l’animazione di cambio. Questo differisce da viewWillAppear, che viene attivato all’inizio del cambio. Se una scheda ha un’animazione di benvenuto o è necessario tracciare il tempo attivo, viewDidAppear è il posto giusto.
Quando l’app torna dallo sfondo al primo piano, il controller visibile può avere viewWillAppear e viewDidAppear chiamati se il ciclo di vita della View è stato temporaneamente sospeso. Tuttavia, per un tracciamento affidabile del ritorno dallo sfondo, utilizza separatamente UIApplication.willEnterForegroundNotification.
viewDidAppear gestisce compiti che richiedono uno schermo visibile per una corretta esecuzione. Esaminiamo gli scenari di utilizzo principali in progetti reali.
Il compito più comune di viewDidAppear è il tracciamento delle visualizzazioni dello schermo. I sistemi di analisi come Firebase Analytics, Amplitude o Mixpanel dovrebbero ricevere eventi solo dopo che lo schermo è stato effettivamente mostrato all’utente. Inviare un evento in viewWillAppear può sottostimare il tempo di visualizzazione e creare falsi inneschi.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Analytics.logEvent(
name: "screen_view",
parameters: [
"screen_name": "ProfileScreen",
"screen_class": String(describing: self)
]
)
}
Le animazioni che devono iniziare dopo l’apparizione dello schermo — apparizione graduale degli elementi, parallasse, tutorial — vengono avviate in viewDidAppear. A questo punto, il contesto grafico è completamente pronto e l’animazione sarà fluida, senza perdita di fotogrammi all’inizio. Questo è particolarmente importante per le animazioni che utilizzano UIViewPropertyAnimator.
Le operazioni asincrone pesanti — caricamento di immagini ad alta risoluzione, analisi di grandi JSON, inizializzazione di video — è meglio avviarle in viewDidAppear piuttosto che in viewDidLoad o viewWillAppear. Quando il metodo viene chiamato, l’utente vede già l’interfaccia, quindi puoi mostrare uno scheletro o un caricatore senza ritardare l’apparizione dello schermo.
Se lo schermo contiene elementi che richiedono aggiornamenti periodici — timer di conto alla rovescia, indicatore di progresso, animazione di progresso — vengono avviati in viewDidAppear e fermati in viewDidDisappear. Questo impedisce ai timer di funzionare quando lo schermo non è visibile, risparmiando batteria e risorse CPU.
I contenuti multimediali — video, audio, animazioni Lottie — vengono avviati in viewDidAppear, non prima. Se inizi la riproduzione in viewWillAppear, l’utente perderà i primi secondi mentre lo schermo sta ancora apparendo. In viewDidAppear, puoi avviare un AVPlayer o un’animazione Lottie con la certezza che l’utente veda il contenuto dal primo fotogramma. Questo è particolarmente importante per le schermate di onboarding e le schermate di avvio dove il tempismo preciso è fondamentale.
Il momento giusto per avviare un’animazione influisce direttamente sulla percezione della fluidità dell’interfaccia. La differenza tra iniziare in viewWillAppear e viewDidAppear può essere impercettibile per animazioni semplici, ma diventa critica per scene complesse.
Quando UIKit esegue una transizione push tra schermi, acquisisce screenshot, li anima e contemporaneamente chiama viewWillAppear sul nuovo controller. Se a questo punto avvii un’animazione pesante — parallasse, sfocatura, trasformazione — UIKit potrebbe perdere fotogrammi dell’animazione di transizione, creando un effetto a scatti. viewDidAppear garantisce che l’animazione di transizione sia completa, dandoti il controllo totale sul rendering.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(
withDuration: 0.6,
delay: 0.3,
usingSpringWithDamping: 0.8,
initialSpringVelocity: 0.5
) {
self.cardView.alpha = 1.0
self.cardView.transform = .identity
}
}
Usa ritardi e smorzamento per creare un’apparizione a cascata naturale degli elementi. Questo approccio migliora la percezione dell’interfaccia e aumenta il tempo di permanenza — gli utenti trascorrono più tempo esplorando i contenuti, il che ha un impatto positivo sulle metriche comportamentali.
L’uso scorretto di viewDidAppear può portare a problemi di prestazioni, comportamento imprevisto delle animazioni e tracciamento eccessivo. Esaminiamo gli errori comuni.
Il primo errore sono le chiamate multiple. viewDidAppear può essere chiamato più volte in certi scenari: cambio di schede, ritorno dallo sfondo, transizioni modali. Se il metodo esegue un’operazione pesante senza controllare un flag, verrà duplicato. Usa un flag hasAppeared o dispatchOnce per azioni singole.
Il secondo errore è avviare richieste di rete senza cancellazione durante l’occultamento. Se l’utente esce dallo schermo prima che la richiesta sia completata, il risultato potrebbe essere applicato a una View già nascosta. Usa URLSessionTask cancellabili e cancellali in viewDidDisappear.
Il terzo errore è il tracciamento in viewWillAppear invece che in viewDidAppear. Alcuni sviluppatori inviano eventi di analisi in viewWillAppear, ma questo crea falsi inneschi se lo schermo non è apparso (ad esempio, a causa di un gesto pop annullato). viewDidAppear è l’unico indicatore affidabile che l’utente ha effettivamente visto lo schermo.
Il quarto errore è dimenticare super. La chiamata a super.viewDidAppear è necessaria per il corretto funzionamento di UINavigationController, UITabBarController e UISplitViewController. Senza di essa, i meccanismi standard di navigazione e aggiornamento dell’interfaccia possono rompersi.
Il quinto errore è cambiare l’orientamento o la dimensione dello schermo senza considerare viewDidLayoutSubviews. Se la tua animazione in viewDidAppear dipende dalle dimensioni finali della View, ricorda che viewDidLayoutSubviews potrebbe essere stato chiamato più volte prima di viewDidAppear. Al primo apparire dello schermo, il layout viene completato prima che viewDidAppear venga chiamato, ma in successivi cambiamenti di dimensione — ad esempio, durante la rotazione del dispositivo — viewDidAppear potrebbe non essere chiamato e la tua animazione non partirà. In questi casi, usa viewDidLayoutSubviews con un controllo del flag firstLayout.
Un’implementazione corretta implica mantenere un riferimento all’oggetto di animazione e cancellarlo esplicitamente quando si lascia lo schermo. Il sesto errore è avviare animazioni infinite senza un flag di arresto. Se avvii un’animazione ripetitiva in viewDidAppear (ad esempio, un indicatore pulsante o un caricatore rotante) ma non la fermi in viewDidDisappear, l’animazione consumerà risorse GPU anche quando lo schermo è nascosto. Mantieni sempre un riferimento all’animazione attiva e chiama removeAllAnimations o setCompletion nel metodo del ciclo di vita corrispondente.
Il settimo errore è ignorare viewDidDisappear per fermare le attività. Se hai iniziato ad ascoltare GPS, accelerometro o giroscopio in viewDidAppear, assicurati di fermarlo in viewDidDisappear. Altrimenti, i sensori continueranno a funzionare in background, scaricando la batteria, anche se l’utente è passato da tempo a un altro schermo. Usa chiamate accoppiate di avvio e arresto nei corrispondenti metodi del ciclo di vita — questo garantisce una corretta gestione delle risorse del dispositivo.
Domande frequenti
viewWillAppear viene chiamato prima dell’animazione di apparizione, quando lo schermo non è ancora visibile. viewDidAppear viene chiamato dopo che l’animazione è completamente terminata, quando lo schermo è visibile e disponibile per l’interazione.
In viewDidAppear, l’animazione di transizione di UIKit è già terminata e tutte le risorse di rendering sono disponibili per il tuo controller. Avviare le animazioni prima può causare perdita di fotogrammi e un’interfaccia a scatti.
In un ciclo di vita normale, no — viewDidAppear segue sempre viewWillAppear. Tuttavia, in alcuni scenari di ripristino dello stato, il sistema può chiamare solo viewDidAppear.
Aggiungi un controllo flag firstAppearance o usa una combinazione di contatore e nome dello schermo. Ad esempio, invia l’evento screen_view solo quando firstAppearance = true, quindi reimposta il flag.
Quando si torna dallo sfondo, UIKit può chiamare viewDidAppear sul controller visibile se la View è stata scaricata dalla memoria. Per un tracciamento affidabile, usa le notifiche di AppDelegate.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche