viewWillAppear — је метода UIViewController коју UIKit позива сваки пут пре него што екран постаје видљив за корисника. Према Apple Developer Documentation, ова метода прима булев параметар animated који указује да ли се прелаз одвија са анимацијом. viewWillAppear — је главно место за ажурирање података и синхронизацију стања екрана.
Главно
viewWillAppear — је метода UIViewController коју UIKit позива непосредно пре него што дода View у хијерархију прозора. У овом тренутку View већ има коначне димензије након пролазака Auto Layout, али још увек није видљива кориснику — анимација преласка се или није започела, или је у току. Програмер прегаза ову методу да би извршио операције које би требало да се десе пре сваког приказивања екрана.
За разлику од viewDidLoad који се позива једном, viewWillAppear се позива сваки пут када би екран требало да се појави: при почетном отварању, при повратку са подреде контролера, након затварања модалног прозора и при пребацивању картица TabBar. То га чини кључном методом за одржавање ажурног стања интерфејса.
Метода прима параметар animated типа Bool, који је true ако је појављивање екрана праћено анимацијом. Овај параметар је згодан за прослеђивање методама NavigationBar и TabBar које такође имају аналоган параметар за усклађено понашање.
Време позивања viewWillAppear зависи од типа навигације, али опште правило је непромењиво: метода се позива пре него што View постаје видљиво. Размотримо главне сценарије.
Након позивања viewDidLoad, UIKit започиње припрему за приказ: View се додаје у хијерархију, покрећу се проласци layout, и непосредно пре почетка анимације преласка позива се viewWillAppear. У овом тренутку екран још увек није видљив, али сви subviews имају исправне димензије и њихов садржај се може безбедно ажурирати.
Када корисник притисне дугме назад или програмски позове popViewController, UIKit се враћа на претходни екран и позива viewWillAppear на њему. Ово је главни сценаријо за који се користи viewWillAppear — ажурирање листе након додавања елемента или синхронизација подешавања.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
Након затварања модално представљеног контролера, UIKit позива viewWillAppear на контролеру који га је представио. Овај сценаријо захтева посебну пажњу ако користите delegateе или closure-е за преношење података назад — viewWillAppear гарантује да ће се екран ажурирати након примана резултата.
TabBarController позива viewWillAppear на контролеру изабране картице сваки пут при пребацивању. Ако се на картици приказују динамички подаци — девизни курсеви, обавештења, статус корисника — viewWillAppear је идеално место за њихово ажурирање.
viewWillAppear решава неколико конкретних задатака који се не могу извршити или нису оптимални у другим методама. Размотримо главне.
Најчешћа употреба viewWillAppear — поновно учитавање UITableView или UICollectionView при сваком појављивању екрана. Ако су се подаци могли променити на претходном екрану (додавање елемента, промена статуса), позивање reloadData у viewWillAppear гарантује да корисник види ажурне информације.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
У viewWillAppear се згодно конфигурише изглед NavigationBar: сакривање или приказивање, промена боје, постављање large title. Ако на различитим екранима NavigationBar изгледа другачије, viewWillAppear је право место за ове промене, јер се viewDidLoad позива само једном.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
Обавештења која имају смиса само када је екран видљив — тастатурна, обавештења о промени садржаја — претплаћују се у viewWillAppear и отказују у viewDidDisappear. То спречава непотребне handlerе када екран није активан и штити од цурења меморије.
Ако екран може бити сакривен апликацијом или умањен, viewWillAppear је згодно место за обнављање стања UI: пребацивање сегмената, обнављање позиције скрола, ресетовање привремених промена. Корисник добија екран у предвидивој форми при сваком појављивању.
На екранима који приказују бројаче непрочитаних порука, оцена или обавештења, viewWillAppear је право место за њихово ажурирање. Ако је корисник могао променити број на другом екрану, овде се позива прерачунавање и ажурирање UITabBarItem.badgeValue или прилагођених показатеља. То гарантује да корисник увек види ажурне бројеве без обзира на то колико је дуго боравио на другим екранима.
Одвојено ваља поменути рад са collectionView: ако су подаци на екрану представљени у облику мреже са ћелијама које садрже бројаче или статусе, њихово ажурирање у viewWillAppear мора бити селективно. Уместо пуног reloadData користите reloadItemsAtIndexPaths за видљиве ћелије да бисте избегли трептења и губитка позиције скрола.
Разумевање разлике између viewWillAppear и viewDidLoad — основа исправне архитектуре UIViewController. Ове методе имају различиту учесталост позивања, различит контекст и различиту намену.
viewDidLoad се позива једном и је погодан за конфигурацију која се не мења током времена: регистрација ћелија, постављање delegateа, иницијализација констаний. viewWillAppear се позива при сваком појављивању и је погодан за операције које се морају понављати: ажурирање података, конфигурисање видљивих елемената, синхронизација стања.
| Карактеристика | viewDidLoad | viewWillAppear |
|---|---|---|
| Учесталост | Једном | Сваки пут при појављивању |
| View видљив | Не | Не (ускоро ће постати видљив) |
| Димензије View | Нису коначне | Коначне |
| Погодан за | Једнократну конфигурацију | Ажурирање и синхронизацију |
| Анимација | Не примењује се | Параметар animated |
Златно правило: ако се операција мора извршити само једном — ставите је у viewDidLoad. Ако сваки пут при повратку на екран — ставите је у viewWillAppear.
Неправилна употреба viewWillAppear може да доведе до проблема са перформансом, прекомерних ажурирања и неконзистентног стања интерфејса. Размотримо најчешће грешке.
Прва грешка — дуплирање логике из viewDidLoad. Ако региструјете ћелије табеле и у viewDidLoad и у viewWillAppear — регистрација ће се извршавати вишекратно, иако је једнократна конфигурација довољна. Пренесите све једнократне конфигурације у viewDidLoad.
Друга грешка — безусловно reloadData при сваком појављивању. Ако се подаци нису промењени, поновно учитавање табеле изазива непотребне упите ка извору података и поновно цртаће ћелија, смањујући перформанс. Проверите да ли се стање стварно променило пре позивања reloadData.
Трећа грешка — рад са мрежним захтевима без узимања да екран може да буде поново сакривен пре завршетка захтева. Ако у viewWillAppear покрећете URLSession захтев, а корисник одмах оде на други екран, резултат може бити примењен на већ сакривени View. Користите отказиве задатке или проверавајте isViewLoaded и window пре ажурирања.
Четврта грешка — заборавили сте да позовете super. Непозивање super.viewWillAppear може да поремети рад родитељских контролера (UINavigationController, UITabBarController) и доведе до неправилног процесирања гестова и прелазака. super се мора увек позивати.
Пета грешка — промена ограничења без позивања layoutIfNeeded. Ако у viewWillAppear програмски мењате ограничења, UIKit их не примењује одмах — промене се акумулирају до следећег проласка layout. За тренутно примењивање промена након модификације ограничења, позовите view.layoutIfNeeded(). Ово је посебно важно при постављању висине елемената зависних од садржаја.
Шеста грешка — покушај да се анимација изврши у viewWillAppear. Као што је горе наведено, UIKit још увек обрађује анимацију преласка, а ваша анимација може да се такмичи са системском. Ако је потребно да се елеменат појави са ефектом, користите улазну анимацију у viewDidAppear, а у viewWillAppear конфигуришите само почетно стање: транспаренција 0, трансформ у размери 0.8 и тако даље.
Седма грешка — игнорисање параметра animated. Неки програмери не проверавају вредност animated у viewWillAppear и извршавају операције које би требало да зависе од присуства анимације. На примјер, сакривање NavigationBar при animated = false може да се уради без анимације, а при animated = true — са анимацијом, да би прелазак изгледао глатко. Увек прослеђујте параметар animated одговарајућим методама UIKit.
Осма грешка — модификација UI на невидљивом екрану. Ако у viewWillAppear покрећете мрежни захтев, а његов блок завршетка ажурира UI када је екран могао већ да нестане, корисник ће видети трептење или неконзистентно стање. Увек проверавајте isViewLoaded и window пре ажурирања UI у closureима. Ова једноставна радња спречава падове и непотребно прецртавање интерфејса.
Често постављана питања
viewWillAppear се позива пре почетка анимације појављивања, када View још није видљив. viewDidAppear — након завршетка анимације, када се екран потпуно приказао и је доступан за интеракцију.
У нормалним условима viewWillAppear се увек позива при појављивању екрана. Изузетак — принудно гашење апликације (force quit), када UIKit не стиже да позове методе Lifecycle.
Да, обавезно. UIKit користи овај позив за унутрашњу координацију са UINavigationController и UITabBarController. Без super могу да се покваре гестови и анимације прелазака.
При сваком пребацивању картице. UIKit позива viewWillAppear на контролеру изабране картице чим корисник дотакне одговарајућу иконицу у TabBar.
Користите својства контролера или заједнички data source. Пре позивања popViewController поставите потребне вредности на претходном контролеру и у његовом viewWillAppear ће већ бити доступне.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође