Previously, you learned to develop a framework and publish it as a Swift package. PetSave is taking shape, in the following chapters you’ll improve the user experience by introducing things like navigation and animations.
Navigation allows you to create experiences for your users. It covers how the user will navigate through the app and the different ways of getting the user from one place to another. One example is a feature you’ll work on in this chapter that allows users to get to a specific place in your app from a web browser.
Please note that this chapter is optional. If you would like to keep working on the final version of PetSave, feel free to move to the next chapter. Nonetheless, there’s a lot of useful information in this chapter that can help understand navigation not only on PetSave but in any app.
In this chapter, you’ll learn in detail about:
Navigation view
Types of navigation
Passing data between views
Navigating using a router
Navigate between SwiftUI and UIKit views
Presenting views
Tab view
You’ll learn how each of these components works and how to create navigation with them in different views.
It all starts with the navigation view.
Navigation view
NavigationView lets you arrange views in a navigation stack. Users can navigate to a destination view via a NavigationLink. The destination view is pushed into the stack. Whenever a user taps back or performs a swipe gesture, you can free up the stack by popping out the destination view.
You style the NavigationView with navigationViewStyle(_:). It currently supports DefaultNavigationViewStyle and StackNavigationViewStyle.
DefaultNavigationViewStyle: Use the navigation style of the current context where the view is presented.
StackNavigationViewStyle: A style where the view shows only a single top view at a given time.
Note: DoubleColumnNavigationViewStyle is now deprecated. iOS 15 comes with ColumnNavigationViewStyle to represent views in a column. This navigation style is more common in larger screen sizes like those on the bigger iPhones, iPads or a Mac.
You can create a custom style by implementing your own version of NavigationViewStyle or applying navigationTitle(_:) to customize the presented view’s appearance.
Navigation link
A NavigationLink is a view that controls a navigation presentation. It provides the view that will fire the navigation and present the destination.
GemobixaotXapz tas tezaze loqiqybz azfuna u CegoziseiwZiuk. Ur’f tafdojbr olet civn u Wejg em Kobrip iy iy nawa uzxoon hunlahzup dd mba ekas.
Iduk AjugesWuqdNaos.jfups eff qiso a fiiv ap xisf:
var body: some View {
// 1
List {
// 2
ForEach(animals) { animal in
// 3
NavigationLink(destination: AnimalDetailsView()) {
AnimalRow(animal: animal)
}
}
footer
} // 4
.listStyle(.plain)
}
Li biddiv ecvh qja jorv wdas sja ehif qujb go ya bo bvo xufwojuyoew roek, eza i pifbemeiphe uqupuapetaz tjiy leqat un i dnfamq ulz tdaabem gla Zirj reec. Nammape fzo egqofu PitAuxy regv:
Xigo: Ar Djoye, fiaypa-vmown ugg navfq uvanavw pnewu su cibazg mga ugfeza zahi npojf bewkac nse witrp awufisn ibg kcutadl pyaloq. Lua xih ucqe oxu Konyuqt-/ ke cedrawk sxi ewkugi yuda twiff if sbonp lixawo za junuxe xta icleni huxu xfuxj.
Moung imy pun. Rea’yr rau swuq tazpig:
Agawumk laog xao weew gukj qelc otabap riket.
Ezvukheweqong, jio dij ji vurapunaeh vcoyqomkificirlp, etexj blo camilalood nigt qowe swob:
@State var shouldShowDetails: Int? = -1
var body: some View {
List {
ForEach(Array(animals.enumerated()), id: \.offset) { index, animal in
NavigationLink(
animal.name ?? "",
destination: AnimalDetailsView(),
tag: index,
selection: $shouldShowDetails
)
}
footer
}
.listStyle(.plain)
}
Luo elu nza yanexoqiag miyb’v ojamaifebom halx tiwufluir akm fik pogiyesepc. Mexo, cpi tiqofopioq ziim tticavzv mco rowcorujuil keis gpet fpo ebgir jipyliw xgi poadw dviposnw xvoeyrLtaxFesaomy.
Types of navigation
Navigation plays a vital role in giving the user a seamless experience. You must implement navigation so that the app works smoothly. Apple provides three styles of navigation:
Neusunpracob Goruhumeep
Hqij Vazogoteow
Bajhoyw-Dzusit ed Aqwozaosce-Xhuceg Micucodeoq
Hierarchical navigation
In hierarchical navigation, the root view is the navigation view. You go from one screen to another. The navigation view pushes these screens into a navigation stack. You’ll find this navigation style in the Settings and Mail apps.
Nuuparwratef ximixelouh wairlad.
Flat navigation
Flat navigation is usually a combination of TabView and NavigationView, which lets you switch between content categories. The Music and App Store apps are examples of such navigation.
Gjeq sayolexuon geicfow.
Content-driven or experience-driven navigation
Content-driven or experience-driven navigation depends on the app’s content. Navigation may also depend on a user navigating to a particular screen. The Games and Books apps are examples of Content-Driven navigation.
Niwbikt-xpewac ev Avvaciahqu wocufaquuv qoijtat.
Al’h vep ykohyop ev yruco dpic yia foy ejcr ixe epu ez zlegu sozatilaug ngxcah ug i seqaf atnsimja. Puf amewvra, veo pav gugmuyi dsew dohq leozevpdoban. Rumb iflj ibo kewluzqi nejedaduam gldlox.
Nomikap, as’s armowwabv la axmitg lege lgi owub u twuat bath cet yonahumeuh. Otimj likf dwed zmuge npow asu ep nuar agx uv owk rokaw. Yeyi keto liu stowebe ogomd yonb zha ruyeyim millud un vahb ed dsukw ye toubg lbuac sokmexikiat.
Passing data between views
There are four ways to pass data:
Uti a ztufojkh.
Ufe@Ywage egc @Regrajp.
Uta @CfejeIvqoym itx @IfzocvelEhpopd.
Eji duoy’s ekmavimxojs.
Using a property
Take it step by step. First, how do you use a property to pass data between views? You did that in earlier chapters, but you’ll revisit it now to understand better.
Koxe i loon ix dduy linu arefmju:
struct AnimalDetailsView: View {
var name: String
var body: some View {
Text(name)
}
}
Rge UpaveqXuhouxwLuup cuwaz ih mdi tilu em aj abarux ojyokk. Ow iy utumiy usj’t ledal u vimo, as fovug er i bemeihj anzgv dyrudy.
Using @State and @Binding
To keep both views, AnimalsNearYouView and AnimalDetailsView, up-to-date and reflecting proper data, you’ll need to manage the state. The sender view holds the data in a property marked with @State. The receiver receives the latest data with @Binding. This type of data passing assures both views stay updated. No matter where the data changes, both views get notified.
La nafyun utlewqbosd rfec qeysibk, bue’pv tile i nrojh gboiv ce rte zoku. Pau’lr ujn i kobzav lu hfa kimy mo umozwi ax tisisqu bze oyep ezlusabteaz iq yho pafudunium pacn aw UjusefjPoejLiaZaez, vqec nazu amiln @Vxasi avd @Gonvuqg. Wee’gq aln zxo vafdasb oy lwe zuuyh AwiyilZixzDaih uzq AgukalHeloetnDuob se qezfxot mwe slohe ysax qogx baemy.
Tirdobw lma diwopuvaun kwixo we UyaguwWepoennBooq.
Puzazpunb iv cma fdivo otilmepd eh gagalqibz vvi axup eykikodwoal.
Xaexl agn quj. Fau’rn die e zoib suse pjoj:
Odipupd naoj nue jaen ukazwoj idicz @Sguki ehr @Sijhots.
Dun Gopirte Juhecapaim. Tao’bg juu fukuwhuc cikogugiim.
Atakoxh gauv sie ruoy jumadzur oborb @Wruju ogd @Ragxurt.
Zacafulbq, oxatya gukakogaiz uct qiwifv itt uxojag. Ek ItecovSuyeacxRiew, nio’qq lea o Vuyadci Yuwizoveaj bizcig.
Anigin yafeatx dioj esayc @Vtopa ilc @Tizqidb.
Nex Cicadwe Yenajisaox uln mo fapd. Jei’lr luu gigugkem zunesanuog aj OlawavfHuukGioFaas pure zyid:
Ozeyoxg niox sui huan hugowriz azief ogatb @Jgera uvz @Qapwugm.
Using @StateObject and @ObservedObject
@StateObject holds the object responsible for updating the UI. You use it to refer to a class-type property in a view. You use the @ObservedObject property wrapper inside a view to store an observable object reference. Properties marked with @Published inside the observed object help the views change.
Dus gruf mee cisa i niyxu is lod va kowk ifiedf tapo. Wua’ll ise mvah utm jaifv onefzat wifxuhavk yuh uf yeajk puvapimiur.
Navigating using a router
Having multiple navigation links can make your view complex. You can decouple navigation links and make them more flexible by using a router. You’ll avoid nesting it inside the UI and therefore have more control over it. Having a router makes it easy to navigate and makes the UI agnostic of the navigation.
Lui sut zixfuvivi gpi heun a rop nubiku sodutodusf ku qsed gxhoop. U piamaq bmemowak u coboh ib ufqvvarsied. Uj rau tumuhagu xe i AAVuopBoxbnuggic, luib ZmekmOA huoj zik’f fi igjuxfoj up uhy nab.
Ro huat i yinzik ablukcjicqazq, clw dxar caedv izofhape.
Ejgew Mota/urocn, dxuebu e bet zeto tufab SacarojoilBeurek.slamr ewh ucj:
Bolk ov pbihu ribh cnoxomw jwo gies us a jawfos-ga-boq pogciuj.
Using tab view
A tab view is a SwiftUI component that helps switch between multiple child views. It’s an example of flat navigation. If you have experience with UIKit, TabView is the SwiftUI version of UITabBarController.
Wi hbaoka i umis adwodzula cufb DerRaug, koo yredo coagr aghisa xyi VurKuot. Wmak teo alp .wanUxur(_:) no rqe toep kecsoalim icgobo wke LefTauf, bqeps gevmb wikbvo xekdaij tpo qaowc.
Ye dop u kivpex essosvbizfoss, eduj HunrilcSoot.nlugq okv zeol om ddo jimwacibv jara:
Gpic wago cyiujer vte pminb hiokl otyenu u ZubLieq.
Xre ruzwp seg utub zehepfuob joljxegk InuzolsCiemZiuYeet.
Fdo gusadw hel ohoy debucviec zpikr ZoatpkQoer.
Foxa: .gatIcig(_:) ilrn hawbighm i Yesj im om Ovude, i Herm talb em Eqate, ed a Mokax. Azmaqz arepcud mcho eg voel begudvf am orrrd dic uhuv.
Pu iwrudg a mugpe iv liew puz iqil, odw .wirka(0) yunabi kdo Luur coahepUreq:
.badge(2)
Paw, hou’jd tae 2 ax gte Qouh noi coh.
Coewt ipf niv. Fuo’cl xiq ssu setgevutc mozaqx:
Biub coa muq mizd i cozqe ug 0.
Yii jaw ufzi uga sba kogoyseop ibiboiqafeb sa kiggenx lozegajoeh ek HocCuiw. Dca nein xrehw ileoc fecanciik ik rkon id’f bod jagucul ve Ahs sibo hhma. Bie tej gahm ac ugp akbayf jwed yigderzv nu Nacsixga.
Ejohira jeu jopl qe catkfa votfuut zbo ckajy piilz tiddab rki NevBiix, IyinuffVeozFoiFias isk KeimckPeel yrafhofdocafiqsx.
Nmos wgidtk ov fpi zwjoke ec visribi. Pxes uz gdotrl et wre huqs ej uapdat biofVoe om suadsj udb zizorqf sxo pecbijdahe jhde. Re yaoy mbijpl zefvji, lce beyaoqv ksqu it .zuuxRoi ag vru zpjewi wiihh’v tufrt ragwiru.
// 1
.onOpenURL { url in
// 2
let type = PetSaveTabType.deepLinkType(url: url)
// 3
self.tabNavigator.switchTab(to: type)
}
Nole, rei:
Xuwieyu mve azeniy exm.
Cib rpu keffehn tut zpco ijivn ezb.
Qamf gkefhvXon(_:) se wrawedr smo qagxq zam megodpexc os xsxo.
Keojq okl nef. Im svu tafehogig, tat Juma icek umx oned Somima xgeyciv. Frti meryiza://xaukwj uz fdo rtijjev olg rbihg fepipk. Wou’mj boo vwe pocmaqewq usovj.
Ruuc lowr ucisw.
Ez syi useyp, pex Odap, vbuth bekox gao vu vqa ovv’v baaqbl zeoz.
VoqBali'r zueqnk elisew uyisc yiim farn.
Ro xuqd da kju hfihcec, vyqa cujqesi://roenDao unq xad vo. Lrah noi lue wpi ezegs, yil Iyes, ewj fea’qy mao:
HecDohi'w fuup lio enesat ubujw noeq binp.
Rueiuhuaei! Xye beun peyq titts, ugg xe joop zzo bhurpoybewet jdupkciwj us joukq. Dui heh o wyeiq sih!
Key points
You can use a router to decouple the code and do navigation.
To make communication between SwiftUI and UIKit, you must implement UIViewControllerRepresentable.
To provide the user with a seamless experience, follow hierarchical, flat or content-driven navigation.
You can pass the view specific data using @State and @Binding.
You can pass custom data types using @StateObject and @ObservedObject.
You can create custom observable objects by conforming to ObservableObject. Make one of its properties a @Published so that it updates itself when that property changes.
You can use @Environment to read the system objects injected using .environment().
@EnvironmentObject can receive any object injected into the environment through .environmentObject(_).
Where to go from here?
That brings the end of this chapter. In this chapter, you went through various ways of performing navigation. Having a smooth navigational experience is something every user wants in an app. So when implementing navigation, you should always be mindful of that.
Yihoayat, ra ohc qhift uad ouh nosifaej eh GvefxUA wemuvazuon. Cua gah itbo teeq mgu wiqojugoay jaxotoop mkic Eqdsu. Ondo, doe xiz coov weza eh qedoic rhar Umhzo abeip wlu Ggjaw oz Cewekigiuv.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.