viewWillAppear — este o metodă UIViewController pe care UIKit o apelează de fiecare dată înainte ca ecranul să devină vizibil pentru utilizator. Conform Apple Developer Documentation, această metodă primeşte un parametru boolean animated care indică dacă tranziţia are loc cu animaţie. viewWillAppear — este locul principal pentru actualizarea datelor şi sincronizarea stării ecranului.
Principalele
viewWillAppear — este o metodă UIViewController pe care UIKit o apelează imediat înainte de a adăuga View în ierarhia ferestrelor. În acest moment View are deja dimensiunile finale după trecerile Auto Layout, dar încă nu este vizibilă pentru utilizator — animaţia de tranziţie fie nu a început, fie este în execuţie. Dezvoltatorul suprascrie această metodă pentru a efectua operaţii care trebuie să aibă loc înainte de fiecare afişare a ecranului.
Spre deosebire de viewDidLoad care se execută o singură dată, viewWillAppear este apelat de fiecare dată când ecranul urmează să apară: la deschiderea iniţială, la revenirea de pe un controler copil, după închiderea unei ferestre modale şi la comutarea filelor TabBar. Acest lucru îl face o metodă cheie pentru menţinerea unei stări actualizate a interfeţei.
Metoda primeşte parametrul animated de tip Bool, care este true dacă apariţia ecranului este însoţită de animaţie. Acest parametru este convenabil de transmis metodelor NavigationBar şi TabBar care au un parametru similar pentru un comportament coerent.
Timpul apelării viewWillAppear depinde de tipul de navigare, dar regula generală este neschimbată: metoda se execută înainte ca View să devină vizibil. Să examinăm scenariile principale.
După apelarea viewDidLoad, UIKit începe pregătirea pentru afişare: View este adăugat în ierarhie, se execută trecerile layout, şi imediat înainte de începerea animaţiei de tranziţie este apelat viewWillAppear. În acest moment ecranul încă nu este vizibil, dar toate subview-urile au dimensiuni corecte şi conţinutul lor poate fi actualizat în siguranţă.
Când utilizatorul apasă butonul înapoi sau apelează programatic popViewController, UIKit revine la ecranul anterior şi apelează viewWillAppear la acesta. Acesta este scenariul principal pentru care se foloseşte viewWillAppear — actualizarea listei după adăugarea unui element sau sincronizarea setărilor.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
După închiderea controlerului prezentat modal, UIKit apelează viewWillAppear la controlerul care l-a prezentat. Acest scenariu necesită o atenţie deosebită dacă foloseşti delegaţi sau closure-uri pentru a transmite date înapoi — viewWillAppear garantează că ecranul se va actualiza după primirea rezultatului.
TabBarController apelează viewWillAppear la controlerul filei selectate de fiecare dată la comutare. Dacă pe filă sunt afişate date dinamice — cursuri valutare, notificări, statusul utilizatorului — viewWillAppear este locul ideal pentru actualizarea lor.
viewWillAppear rezolvă câteva sarcini concrete care nu pot fi efectuate sau nu sunt optime în alte metode. Să examinăm principalele.
Cea mai frecventă utilizare a viewWillAppear — reîncărcarea UITableView sau UICollectionView la fiecare apariţie a ecranului. Dacă datele s-ar putea fi schimbat pe ecranul anterior (adăugarea unui element, modificarea statusului), apelarea reloadData în viewWillAppear garantează că utilizatorul vede informaţii actualizate.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
În viewWillAppear se configurează convenabil aspectul NavigationBar: ascunderea sau afişarea acestuia, schimbarea culorii, setarea large title. Dacă pe diferite ecrane NavigationBar arată diferit, viewWillAppear este locul potrivit pentru aceste modificări, deoarece viewDidLoad este apelat doar o dată.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
Notificările care au sens doar când ecranul este vizibil — de tastatură, de modificare a conţinutului — se abonează în viewWillAppear şi se dezabonează în viewDidDisappear. Acest lucru previne handler-ele inutile când ecranul nu este activ şi protejează împotriva scurgerilor de memorie.
Dacă ecranul poate fi ascuns de aplicaţie sau minimizat, viewWillAppear este un loc convenabil pentru restaurarea stării UI: comutarea segmentelor, restaurarea poziţiei scroll, resetarea modificărilor temporare. Utilizatorul primeşte ecranul într-o formă previzibilă la fiecare apariţie.
Pe ecranele care afişează contoare de mesaje necitite, evaluări sau notificări, viewWillAppear este locul potrivit pentru actualizarea lor. Dacă utilizatorul ar fi putut modifica cantitatea pe un alt ecran, aici se apelează recalcularea şi actualizarea UITabBarItem.badgeValue sau a indicatorilor personalizaţi. Acest lucru garantează că utilizatorul vede întotdeauna numere actualizate indiferent de cât timp a petrecut pe alte ecrane.
Separat merită menţionat lucrul cu collectionView: dacă datele de pe ecran sunt prezentate sub formă de grilă cu celule care conţin contoare sau statusuri, actualizarea lor în viewWillAppear trebuie să fie selectivă. În loc de reloadData complet, folosiţi reloadItemsAtIndexPaths pentru celulele vizibile pentru a evita pâlpâirea şi pierderea poziţiei de scroll.
Înţelegerea diferenţei dintre viewWillAppear şi viewDidLoad — baza arhitecturii corecte UIViewController. Aceste metode au frecvenţă diferită de apelare, context diferit şi scop diferit.
viewDidLoad este apelat o dată şi este potrivit pentru configurarea care nu se schimbă în timp: înregistrarea celulelor, setarea delegaţilor, iniţializarea constantelor. viewWillAppear este apelat la fiecare apariţie şi este potrivit pentru operaţii care trebuie repetate: actualizarea datelor, configurarea elementelor vizibile, sincronizarea stării.
| Caracteristică | viewDidLoad | viewWillAppear |
|---|---|---|
| Frecvenţă | O singură dată | De fiecare dată la apariţie |
| View vizibil | Nu | Nu (va deveni vizibil curând) |
| Dimensiunile View | Nu sunt finale | Finale |
| Potrivit pentru | Configurare unică | Actualizare şi sincronizare |
| Animaţie | Nu se aplică | Parametrul animated |
Regula de aur: dacă operaţia trebuie să se execute o singură dată — puneţi în viewDidLoad. Dacă de fiecare dată la revenirea pe ecran — puneţi în viewWillAppear.
Utilizarea incorectă a viewWillAppear poate duce la probleme de performanţă, actualizări excesive şi stare inconsecventă a interfeţei. Să examinăm cele mai frecvente greşeli.
Prima greşeală — duplicarea logicii din viewDidLoad. Dacă înregistraţi celulele tabelului atât în viewDidLoad cât şi în viewWillAppear — înregistrarea se va executa de mai multe ori, deşi configurarea unică este suficientă. Mutaţi toate configuraţiile unice în viewDidLoad.
A doua greşeală — reloadData necondiţionat la fiecare apariţie. Dacă datele nu s-au schimbat, reîncărcarea tabelului cauzează cereri suplimentare la data source şi redesenează celulele, reducând performanţa. Verificaţi dacă starea s-a schimbat cu adevărat înainte de a apela reloadData.
A treia greşeală — lucrul cu cereri de reţea fără a considera că ecranul poate fi ascuns din nou înainte de finalizarea cererii. Dacă în viewWillAppear lansaţi o cerere URLSession, iar utilizatorul pleacă imediat pe un alt ecran, rezultatul poate fi aplicat unui View deja ascuns. Folosiţi sarcini anulabile sau verificaţi isViewLoaded şi window înainte de actualizare.
A patra greşeală — aţi uitat să apelaţi super. Neapelarea super.viewWillAppear poate perturba funcţionarea controlerelor părinte (UINavigationController, UITabBarController) şi poate duce la procesarea incorectă a gesturilor şi tranziţiilor. super trebuie apelat întotdeauna.
A cincea greşeală — modificarea constrângerilor fără a apela layoutIfNeeded. Dacă în viewWillAppear modificaţi programatic constrângerile, UIKit nu le aplică imediat — modificările se acumulează până la următoarea trecere layout. Pentru aplicarea imediată a modificărilor după modificarea constrângerilor, apelaţi view.layoutIfNeeded(). Acest lucru este deosebit de important la setarea înălţimii elementelor dependente de conţinut.
A şasea greşeală — încercarea de a executa animaţia în viewWillAppear. După cum s-a menţionat mai sus, UIKit încă procesează animaţia de tranziţie, iar animaţia dumneavoastră poate concura cu cea de sistem. Dacă aveţi nevoie ca un element să apară cu efect, folosiţi animaţia de intrare în viewDidAppear, iar în viewWillAppear configuraţi doar starea iniţială: transparenţă 0, transform la scară 0.8 şi aşa mai departe.
A şaptea greşeală — ignorarea parametrului animated. Unii dezvoltatori nu verifică valoarea animated în viewWillAppear şi execută operaţii care ar trebui să depindă de prezenţa animaţiei. De exemplu, ascunderea NavigationBar la animated = false se poate face fără animaţie, iar la animated = true — cu animaţie, pentru ca tranziţia să arate lină. Transmiteţi întotdeauna parametrul animated metodelor corespunzătoare UIKit.
A opta greşeală — modificarea UI la un ecran invizibil. Dacă în viewWillAppear lansaţi o cerere de reţea, iar blocul său de completare actualizează UI când ecranul ar fi putut deja să dispară, utilizatorul va vedea pâlpâiri sau o stare inconsecventă. Verificaţi întotdeauna isViewLoaded şi window înainte de a actualiza UI în closure-uri. Această acţiune simplă previne crash-urile şi redesenările inutile ale interfeţei.
Întrebări frecvente
viewWillAppear este apelat înainte de începerea animaţiei de apariţie, când View încă nu este vizibil. viewDidAppear — după încheierea animaţiei, când ecranul s-a afişat complet şi este disponibil pentru interacţiune.
În condiţii normale viewWillAppear este întotdeauna apelat la apariţia ecranului. Excepţie — închiderea forţată a aplicaţiei (force quit), când UIKit nu reuşeşte să apeleze metodele Lifecycle.
Da, obligatoriu. UIKit foloseşte acest apel pentru coordonarea internă cu UINavigationController şi UITabBarController. Fără super se pot strica gesturile şi animaţiile de tranziţie.
La fiecare comutare a filei. UIKit apelează viewWillAppear la controlerul filei selectate imediat după ce utilizatorul atinge pictograma corespunzătoare în TabBar.
Folosiţi proprietăţile controlerului sau o sursă de date comună. Înainte de a apela popViewController, setaţi valorile necesare pe controlerul anterior, iar în viewWillAppear al acestuia vor fi deja disponibile.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și