viewWillAppear — je metoda UIViewController, kterou UIKit volá pokaždé, než se obrazovka stane viditelnou pro uživatele. Podle Apple Developer Documentation tato metoda přijímá booleovský parametr animated, který určuje, zda přechod probíhá s animací. viewWillAppear — je hlavní místo pro aktualizaci dat a synchronizaci stavu obrazovky.
Hlavní body
viewWillAppear — je metoda UIViewController, kterou UIKit volá bezprostředně před přidáním View do hierarchie oken. V tomto okamžiku má View již konečné rozměry po průchodech Auto Layout, ale ještě není viditelné pro uživatele — animace přechodu buď nezačala, nebo probíhá. Vývojář tuto metodu přepisuje, aby provedl operace, které by měly nastat před každým zobrazením obrazovky.
Na rozdíl od viewDidLoad, který se volá jednou, je viewWillAppear volán pokaždé, když se obrazovka chystá zobrazit: při počátečním otevření, při návratu z podřízeného kontroléru, po zavření modálního okna a při přepínání karet TabBar. To z něj činí klíčovou metodu pro udržování aktuálního stavu rozhraní.
Metoda přijímá parametr animated typu Bool, který je true, pokud je zobrazení obrazovky doprovázeno animací. Tento parametr je vhodné předávat metodám NavigationBar a TabBar, které mají podobný parametr pro konzistentní chování.
Načasování volání viewWillAppear závisí na typu navigace, ale obecné pravidlo je neměnné: metoda se spouští před tím, než se View stane viditelným. Podívejme se na hlavní scénáře.
Po volání viewDidLoad začne UIKit přípravu na zobrazení: View je přidáno do hierarchie, provedou se průchody layout a bezprostředně před zahájením animace přechodu je volán viewWillAppear. V tomto okamžiku obrazovka ještě není viditelná, ale všechna subview mají správné rozměry a jejich obsah lze bezpečně aktualizovat.
Když uživatel stiskne tlačítko zpět nebo programově zavolá popViewController, UIKit se vrátí na předchozí obrazovku a zavolá na ni viewWillAppear. To je hlavní scénář, pro který se viewWillAppear používá — aktualizace seznamu po přidání prvku nebo synchronizace nastavení.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
Po zavření modálně představeného kontroléru UIKit volá viewWillAppear na kontroléru, který jej představil. Tento scénář vyžaduje zvláštní pozornost, pokud používáte delegáty nebo closures k předávání dat zpět — viewWillAppear zaručuje, že se obrazovka aktualizuje po obdržení výsledku.
TabBarController volá viewWillAppear na kontroléru vybrané karty pokaždé při přepínání. Pokud jsou na kartě zobrazena dynamická data — směnné kurzy, oznámení, stav uživatele — viewWillAppear je ideální místo pro jejich aktualizaci.
viewWillAppear řeší několik konkrétních úkolů, které nelze nebo nejsou optimální provádět v jiných metodách. Podívejme se na hlavní z nich.
Nejčastější použití viewWillAppear — opětovné načtení UITableView nebo UICollectionView při každém zobrazení obrazovky. Pokud se data mohla změnit na předchozí obrazovce (přidání prvku, změna stavu), volání reloadData ve viewWillAppear zaručuje, že uživatel vidí aktuální informace.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
Ve viewWillAppear lze pohodlně konfigurovat vzhled NavigationBar: skrýt nebo zobrazit jej, změnit barvu, nastavit large title. Pokud na různých obrazovkách NavigationBar vypadá jinak, viewWillAppear je správné místo pro tyto změny, protože viewDidLoad je volán pouze jednou.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
Oznámení, která mají smysl pouze když je obrazovka viditelná — klávesnicová, oznámení o změně obsahu — se předplácejí ve viewWillAppear a odhlašují ve viewDidDisappear. To zabraňuje zbytečným handlerům, když obrazovka není aktivní, a chrání před úniky paměti.
Pokud může být obrazovka skryta aplikací nebo minimalizována, viewWillAppear je vhodné místo pro obnovení stavu UI: přepínání segmentů, obnovení pozice scrollu, resetování dočasných změn. Uživatel dostává obrazovku v předvídatelné podobě při každém zobrazení.
Na obrazovkách zobrazujících čítače nepřečtených zpráv, hodnocení nebo oznámení je viewWillAppear správné místo pro jejich aktualizaci. Pokud uživatel mohl změnit množství na jiné obrazovce, zde se volá přepočet a aktualizace UITabBarItem.badgeValue nebo vlastních indikátorů. To zaručuje, že uživatel vždy vidí aktuální čísla bez ohledu na to, jak dlouho byl na jiných obrazovkách.
Samostatně je třeba zmínit práci s collectionView: pokud jsou data na obrazovce prezentována ve formě mřížky s buňkami obsahujícími čítače nebo stavy, jejich aktualizace ve viewWillAppear by měla být selektivní. Místo plného reloadData použijte reloadItemsAtIndexPaths pro viditelné buňky, abyste předešli blikání a ztrátě pozice scrollu.
Pochopení rozdílu mezi viewWillAppear a viewDidLoad — základ správné architektury UIViewController. Tyto metody mají různou frekvenci volání, různý kontext a různý účel.
viewDidLoad je volán jednou a je vhodný pro konfiguraci, která se v čase nemění: registrace buněk, nastavení delegátů, inicializace konstant. viewWillAppear je volán při každém zobrazení a je vhodný pro operace, které se musí opakovat: aktualizace dat, konfigurace viditelných prvků, synchronizace stavu.
| Charakteristika | viewDidLoad | viewWillAppear |
|---|---|---|
| Frekvence | Jednou | Pokaždé při zobrazení |
| View viditelné | Ne | Ne (brzy bude viditelné) |
| Rozměry View | Nejsou konečné | Konečné |
| Vhodné pro | Jednorázovou konfiguraci | Aktualizaci a synchronizaci |
| Animace | Nepoužije se | Parametr animated |
Zlaté pravidlo: pokud se má operace provést pouze jednou — dejte ji do viewDidLoad. Pokud při každém návratu na obrazovku — dejte do viewWillAppear.
Nesprávné použití viewWillAppear může vést k problémům s výkonem, nadměrným aktualizacím a nekonzistentnímu stavu rozhraní. Podívejme se na nejčastější chyby.
První chyba — duplikování logiky z viewDidLoad. Pokud registrujete buňky tabulky jak ve viewDidLoad, tak ve viewWillAppear — registrace se bude provádět vícekrát, i když jednorázová konfigurace stačí. Přesuňte všechny jednorázové konfigurace do viewDidLoad.
Druhá chyba — bezpodmínečné reloadData při každém zobrazení. Pokud se data nezměnila, opětovné načtení tabulky způsobuje zbytečné dotazy na data source a překreslování buněk, což snižuje výkon. Zkontrolujte, zda se stav skutečně změnil před voláním reloadData.
Třetí chyba — práce se síťovými požadavky bez ohledu na to, že obrazovka může být znovu skryta před dokončením požadavku. Pokud ve viewWillAppear spustíte požadavek URLSession a uživatel okamžitě přejde na jinou obrazovku, výsledek může být aplikován na již skryté View. Používejte zrušitelné úkoly nebo kontrolujte isViewLoaded a window před aktualizací.
Čtvrtá chyba — zapomněli jste zavolat super. Nevolání super.viewWillAppear může narušit fungování nadřazených kontrolérů (UINavigationController, UITabBarController) a vést k nesprávnému zpracování gest a přechodů. super by měl být vždy volán.
Pátá chyba — změna omezení bez volání layoutIfNeeded. Pokud ve viewWillAppear programově měníte omezení, UIKit je neaplikuje okamžitě — změny se hromadí do dalšího průchodu layout. Pro okamžité uplatnění změn po úpravě omezení zavolejte view.layoutIfNeeded(). To je zvláště důležité při nastavování výšky prvků závislých na obsahu.
Šestá chyba — pokus o provedení animace ve viewWillAppear. Jak bylo zmíněno výše, UIKit stále zpracovává animaci přechodu a vaše animace může konkurovat systémové animaci. Pokud potřebujete, aby se prvek objevil s efektem, použijte vstupní animaci ve viewDidAppear a ve viewWillAppear nakonfigurujte pouze počáteční stav: průhlednost 0, transform v měřítku 0.8 a tak dále.
Sedmá chyba — ignorování parametru animated. Někteří vývojáři nekontrolují hodnotu animated ve viewWillAppear a provádějí operace, které by měly záviset na přítomnosti animace. Například skrytí NavigationBar při animated = false lze provést bez animace, a při animated = true — s animací, aby přechod vypadal hladce. Vždy předávejte parametr animated odpovídajícím metodám UIKit.
Osmá chyba — úprava UI na neviditelné obrazovce. Pokud ve viewWillAppear spustíte síťový požadavek a jeho dokončovací blok aktualizuje UI, když obrazovka mohla již zmizet, uživatel uvidí blikání nebo nekonzistentní stav. Vždy kontrolujte isViewLoaded a window před aktualizací UI v closures. Tento jednoduchý úkon zabraňuje pádům a zbytečnému překreslování rozhraní.
Často kladené otázky
viewWillAppear je volán před začátkem animace zobrazení, když View ještě není viditelné. viewDidAppear — po dokončení animace, když je obrazovka plně zobrazena a dostupná pro interakci.
Za normálních podmínek je viewWillAppear vždy volán při zobrazení obrazovky. Výjimka — vynucené ukončení aplikace (force quit), kdy UIKit nestihne zavolat metody Lifecycle.
Ano, povinně. UIKit používá toto volání pro vnitřní koordinaci s UINavigationController a UITabBarController. Bez super se mohou pokazit gesta a animace přechodů.
Při každém přepnutí karty. UIKit volá viewWillAppear na kontroléru vybrané karty ihned poté, co uživatel klepne na odpovídající ikonu v TabBar.
Použijte vlastnosti kontroléru nebo sdílený data source. Před voláním popViewController nastavte potřebné hodnoty na předchozím kontroléru a v jeho viewWillAppear budou již dostupné.
Shrnutí
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í.
Přečtěte si také