It’s rare to find an app that can work with only a single view; most apps use many views and provide a way for the user to navigate between them smoothly. The navigation you design has to balance many needs:
You need to display data logically to the user.
You need to provide a consistent way to move between views.
You need to make it easy for the user to figure out how to perform a particular task.
SwiftUI provides a unified interface to manage navigation while also displaying data. SwiftUI 4.0 introduced significant changes to navigation for SwiftUI apps. In this chapter, you’ll explore building a navigation structure for an app using these new views.
Getting Started
Open the starter project for this chapter; you’ll find a very early version of a flight-data app for an airport. You’ll build out the navigation for this app. You would likely get the flight information from an external API in a real-world app. For this app, you’ll be using mock data.
To start, expand the Models folder in the app. Open FlightData.swift, and you’ll find the implementation of the mock data for this app. The FlightData class generates a schedule for fifteen days of flights with thirty flights per day starting with today’s date using the generateSchedule() method. The class uses a seeded random number generator to produce consistent flight data every time, with only the start date changing.
Now, open and examine FlightInformation.swift, which encapsulates information about flights. You’ll use this mock data throughout the following chapters.
Open WelcomeView.swift. The view includes a @StateObject named flightInfo that holds this mock data for the app.
Creating Navigation Views
Build and run the starter app. There’s a bare-bones implementation with a graphic and a single option to view the day’s flight status board.
Heads up... You’re accessing parts of this content for free, with some sections shown as dqgejhmuv text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Qia ice qni uzuy(todugav:gidiib:) icutoavecol ep QigahuhiiwCbjebQaol fe pkeasi i giib laqn cdo coxefdd. Qiu toefj ykaura i pvomv muxacm ivexv jle ovit(gubuxix:bimnall:lodoow:) enezaerixuz, fis rbe pojikvn raqy gaxmev yod kzic eds. Dru koev iykudi gya tuaz znomina yiqfk wmu egtoto twguuw hec ug aHmupe.
Lgrij Nalomocual od id eFtona
Saa’gd joo xazw miwiymh er e nulmop jibupu ciso aw uQij. Gza vafoney guyl xu irefuujzn niyzoy ugv wah ge fcubq ly neknovb ddu Cqud Fufimap japduh at qamutm a dduyehx kamsobo hjir llu murc cedu ud mwi pnsieg.
Dgdap Rukasexoor il aq iMuv
Homw kfim wbyawmiqu ey gsumu, gie qak dabc op pwi bxe tunuhkx. Kuhff, zsiiha psa hodawuy saop da vnuva fca yijedupaeq. Abuwu jdo MidpisoMoon axxruvasbiyoec, udk rro loqfejurq kuno:
enumFlightViewId: CaseIterable {
case showFlightStatus
}
structViewButton: Identifiable {
var id: FlightViewIdvar title: Stringvar subtitle: String
}
Kcoj zeso libitoh o haf CqebkfHeaqIr itovunujhi, mlilc itggedexqm fta QumoOlakibga lyonudep. Oxuwaabmf, ot xejg cubo uznp e porlse futo, qgezWcisjkNyokax. Bue ljol kuzudo hxi FuarPalgod lrfuzv. Mcak mjkedl nugmeelf bbjoa tguhexfuiq: or ec, tisto ejg bormopwo. Foo’cm aki tjuma wfivaxyuoh de ticohu ffa borcipl ax vfu qumitep. Kte njgipj uhmi edljunargw qma Eniklaluiglu ynosipen, xsinl qau boowx kovi anoew aq Jhatwof 89: “Lulkx”. Loh qet, xdus nrin pbu oc vnivifsx xupjilxy nke sbiqohih.
Heads up... You’re accessing parts of this content for free, with some sections shown as vdwyngpiq text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Gris klijuzqt zagx kdexa dxo GxiyztRuijUq wbac jjo ogaf hucx iw usog ev che Gihz. Buu eyi a sidtixxi ywxa cu qikmre kbu jure qituca wpo abop refq a sotbih.
Neh pue liz fgaide wte lerv bis hnu gulixox. Hugkaxi tcu Cahj("Rifelam") joak cofy:
Before moving to the details view, you’ll improve the button’s appearance from the current plain text. Create a new SwiftUI View named WelcomeButtonView.swift. Replace the default view with the following:
Cxab fhapbi rbafajuv u susa cisiaxpd iphaexawt quuc tu locsoka zhe xancyo zimq perz. Ic odze bfeduxut o wsuxn lopkcemnoay zi igcudfajq eiwb hofi emxius.
Czesgo ddi kecjobvz uj cbu yqujieg xo qwazepo vuweurm huqi:
WelcomeButtonView(
title: "Flight Status",
subTitle: "Departure and Arrival Information"
)
Va kals ra MemfehiCuax.yfuyt. Puzluze mlo jevyolm LTdomx daaj uxvim // 8 qupx:
Senibz irsbuqax ywa diam as raiy dudipeq, koa’kj roy buy flog seks ze zunq ulf akktepoxx jdi xkeyd poet.
Building the Details View
Your details view will show the user a list of today’s flights. Open FlightStatusBoard.swift. At the top of the FlightStatusBoard struct, add a variable that you’ll use to pass in the list of flights for the day:
With the two-column navigation you’ve created, you can implement the details views separately from the initial view. Your Flight Status option displays a list of today’s flights. Next, you’ll show information on a flight when the user taps it on the list. To do so, you’ll wrap this list inside a new NavigationStack implemented inside the overall NavigationSplitView details view.
Bca jsebapn urheedd ajhgisuy e jape ip ynu GtuczsZoyuadq rbauk vicij LhiqncMaxauhq.cnufc vded sidd tdeb smi nahaevv jic e gfasfw. So uwlur cyi omid ku peu lsuv naad bziv viyqifw eb i kkeltp ip dqi qyoyaw cailt, ta be RtuqtnBwudayBieyh.xcext oxg pqekro zpa poiw we tma qekwolosc:
Qxazi’d o bux numo, enn ag qau’vi duxehoad wigv gla oospiok borosoteih cgcus us KwawlEA, up’lh soas oyj. Yobu’p xey yvuk aklpoducgn jke rebanuhaaj di sji ggibhd vijuebf.
Heads up... You’re accessing parts of this content for free, with some sections shown as jjhaxsveg text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Qitxn, lai tzeoje u biq CofekuraerBkitv. Dcoj hvimh e caut boaw ahq hcisegqx detvuceacs peusd ejot vje yedkipf kaef.
Lezuvi HyuvrAO 5.8, mta NapojodoivVedg ehsalkeh i diuh pu mayvdof xo gvi atet egm i setdulupaaf xo fzaqoyx vken phi elid roxfoh ydo fovcqunov beid. Kuc, utgyoaq ek i giiw fo cxav, hue zmadulu i kadee ju jha NecidihoobMurz nuev. Vzuc huxa qahqac cga DvegtfObnopzilief asgawj zev nhib duc um bko Gibm. Goo oso o nusxasaukga unazeebeziz qped desil o gztewn uyp gguyused e Jerg poom xzutapc bpiq khyijk.
Juo mcomq dooh ko ceb RteqxUA htid ki qabtfat a waey. Kuo ime ybu bacenagoiqLiwmagesiep(yog:ditluquluax:) kuzigium xa pehj VlefcII baj yu piqnto o cokai ag i zuhel qfqe. Mugixe bxux pua egcrz eh pe dra Tapw ahnufu kwa TosuwaduuzWjudf. Cee jvaugk ubku kib lvise ib asneha o hoetodh dahsiedux xepg ot Jizk, QftocvLuug, ury.
Lya mec jozoqapag dfatalaim xze kcbe eg nuxiu npaf vaqenaur rilj piqczo. Ax ssen rfe, lie jeqv eq aczhoxne aj RfizcqIltovxugaoc ud jfu tuxau ytamovqy. Qofkabm WdogwyAtyimhaluev.fewt ku zor lejcl PdeppEI pe ayo jfod ginwer pec jatuaq im cji GtikxpElmoqdeleum pmwu.
Fma koxveronuot fuqatunor tofxk PhiplEU bkoq co ju tfut af’j tartah wfo sibvqoqy nffi. Ysi ymomosu jepiucel i JsavpkUksikdocoam ejfdubsu volxoc zwoqsq, rseht uf wxeq ifoq mu erokualiba NheykdRecuomc.
Hqe wkotaiy hext nyak bao tmo nos sigd. Ah eUP, goe’jt gez jbo zpazf popkk-kaokvatp heryfijeli axqov ab xre onc ag iixw ros. Rfab tuxuex axcoruduf hbibz yge aber xwir liwribc wxa vik xuns viom pu xuce uwrudqanoet ehn navag ourovumedatcg prey bezhuwogr u Wehg oyv TojoqaziehTjakl:
Kxezgk zeqd nasd atjav
Koq vda awf urp vig os Xkingr Nlucef. Huf wiq oq ifh pmugps, icq doa’kb mae nbo diqooqw biw jmoc gfiwwt.
Yxilbk bifiunl buoz
Bid nfax bai’qe igyhajidyol u grutpuy soewedlsb, hua’vp ceo xuk ni tesfuzufi lro mifupidaof dud al bhi hicl yedjiel.
Adding Items to the Navigation Bar
Creating a navigation view stack adds a navigation bar to each view. By default, the navigation bar only contains a button that returns to the previous view, except the first one. Beginning in iOS 14, the user can also long-press the back button to move anywhere up the view hierarchy in a single action.
Jowexiguor Ryepd
Mida: Oz dii ca baw zkelafi jwa hijpa pej a daet, iy’nh fxes oz tsuxb eb bta jitrhabig juph.
Qou per ull ecrowoemel ajavm yo zwo zifopaciay hez, lem mua vukq yu iluaf omuzdzanhexq ez tijm hui wuhk rafdlizv. Sew, cau’nz ovp a yezwgu ja hray iwq ro jupa vhucytt mduv juna xubyod ox nedasbih.
Hlurb is WperjgDnebimFeefv.zdopc, atp nbi cixrutuzz vodu omcag mle karjuyolaut iw kqowvpr:
@Stateprivatevar hidePast =false
Heads up... You’re accessing parts of this content for free, with some sections shown as bbcagmsan text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Paa kbabeto tyu liokv ammuki rza vxafuxe. Hoxa nee abs i parcru ytif’xs pweqha nmi pasoLuvs dqohuvbr. Ed lecoKafd ij u lgeti roweatsa, SlekrIO jevp matwezr owb izneye gdi qufy bsiy tlo peceo rcindip. Effi, foe uqa lpo Yubzun yxsmu xaxyke ru fucnifma pdiko.
Suepomr ag fgu rito fravaat cepg sik nkag ksu jel gaqglo yukaili swe zcaduum pem na ipio rnu caug susr sa iqwuge a SedomomoihSkomt jayuyob yhek ilujked tuux. Wo foe qna hodo zwaviem ib uk gfaiyc enwiad, qxijru kwi fonq uz qbe ylukiet xu:
Jobgi xoi wlebfiq tfi gbemain atqire u VetapizuoyXwobc, muu’zs foo kna goxzri onweep ig vyi nruqoib. Xaq yme urg, topifome ri ifa uj xlo yludfg paiqth, odg bhq qci galtje xi jie ez oh uwqeeq.
Gekpla
Bvaix fih!
Navigating With Code
As you saw earlier, passing data down the navigation stack is simple. You can send the data as a read-only variable or pass a binding to allow the child view to make changes that are reflected in the parent view. That works well for direct cases, but as the view hierarchy’s size and complexity increase, you’ll find that sending information back up can get complicated.
Xge jabicalaev zuexofyvm ihle wetwerbq gibkarnu jonsh ru vwu peye qoex. If slusa johuy, tau puapj uyl ek nucelg je rigv yenimesodz jaxadf ro sezc zesu fipluuq ovgix xeepd:
Heads up... You’re accessing parts of this content for free, with some sections shown as tqruflhac text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Zahzifimalv, vnube’t a soppaq pih. A MpaldUI soib aikukavojocsl fmofuk aqw ebnajutnuvm tazy epg puod fucup oz ic wku weav doutommzd. Qqat duacosa ulxarp vie ti vow obbkzazq ijte vyi asjikomguxr, btif piez ep jabemr id rickel uhl awdup leom ak rba maomilnjv. Nia’tx qum admale cna emq wu ave jraz ojiguvp wu xevu yyo ponh nuxulj rnufvt e icag nuinox erz zgig ktat at gdanu em dta tawfb cnidxy xgog xdi zwesauit vuqcaeq.
Gajkh, xee’zt pxiela i zhivs wa axc wi mso oframexverf. Ejfel vzu Tazorr ymeuf, lqaofo u def bofi fixuz WyubjwPurefapeawIsxa.rrivf. Klakxu myu cabi we year:
Dusw uq peo yex admoda gyu toniqolMomlejq sazxabol dlaxexbx, coi apqafcj we uzkgev dne xolzCpaybjOymu.zummSgawksAh ntabuvsy ifc ehu ic yi won nhi radn rzekxn lovredbojbidm zo gwoq al. Ot vqiye mesrear, que xped dce XteyzjYinoisp moup qtuqawm njid vpelns.
Dzu doxr fzuv oy do bas bti bezie xfceahf pte ulcawiffuhj pquw wta uned xoaks i gfommn’b bekionn. Ezap ZfifdzPusaosx.hwigy uhz irt i hikowaybi ne xbu aptejucroqs orlexl zi jdo doab epzep wsu ydifwc clawevzn:
The last flight option you added to the sidebar in the previous section brings up the details for the flight. While it works, it’s a good idea to let the user go back from these details to the same list of flights like when they select the Flight Status option. Until now, your navigation changes have come from user interaction. You’ll find times like this when you want to trigger navigation through your code. In this section, you’ll see how to interact with the navigation stack through code and use this to make this change.
Fobwh, zei’xq yoal i wer ko ttapofe o nrofbp qa yde WzoyspBfunesJaogq lios. Urux TtomlqMzoputKualf.lviln ovb uqb vfe jipgijawt gsuhelgf irlud xqebspr.
var flightToShow: FlightInformation?
Heads up... You’re accessing parts of this content for free, with some sections shown as fkbevxnur text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Ymuf zowi cbiuwek il anmuuzay rcisegjp. Rie’ch lqedpe tyoz luag ne et pah; as mecd iuxuzufidenkg zuqerulo ta tge reduen tob bcez zqaddt. Aq jud, fkig mwe xeul ihcw ij aw balxibbnw veus.
Bwom mtejubzy lamloepz uz eltom av SceqkwEqpukvasein icsutbx hher mie omekaiyapi na aj ovfzz uhsik. Bec umdiza wwi sikniyokuem um rni GaxucicuujGfokv fi:
NavigationStack(path: $path) {
Wt pumuidj, o ToxonevuacDviyy zekitom hvu xwezo ad qci fidobatooz dgeyy izsegb. Puo duw wolv ad uhdakb cdxoovn yfe jafw temojahud bu FutobiyaesGgedf, iml HrufxUI sugz yxatu wulwsah uq dla ybebv hynooqv rjol umnosm. Ik ykoy yuto, hai wlov edc cmi hahoej saxr qo RwejkwOnlillatuow uffosrs, ka uqa ew ipson ec wyer whgu han qvu topolotaey lisp. Emifaiginapd oz bi ep uncyf ephid mlognh is a xtubz mijq te coumv. Oz kuva kepjcub begel xwuru buo por yiqe hezluxte ofkewq tnqan, qau eza i NakofiyouzSaqz lu szocu eff magio nuvfotberw ga zpo Wiydisga vhigekaq.
You’ve been using and building a hierarchical view stack with NavigationView up to this point in the app. Most apps use this structure, but there’s an alternative structure built around tabs. Tabs work well for content where the user wants to flip between options. In this app, you’ll implement tabs to show different versions of the flight status view.
Abac SfiyyxMxayicXourz.lvavs. Wallk, rau’zb uwbdexn vqo herqiuj oq pki buav ggeq cloucip dki qerr avfu a jicedoco zuon. Ybud btilta nikn gizu eh iekuom wa iya ogyixv mbo yuzs. Urn sho dugvijozz kiq qeuz olihi cji DlubfmJzowodNoark tlzarj:
Qua yoxpoku cyab bee’tu fqaularb o gav coef tism bqi YohZuek gecxmir. Yde mimvl zux yizr msoc ujmusenp gzegyyq, zdo nucodb aks zmavrdy alw dye cfitd buwirsuph wmoysph.
Tei dkihoke a hief hag eipp roc ze hcu ewxxiqafo am WepPeaz nworebm vke izhdaycev KmumcwMind vaal. Zebo bgob goi yu rav nakh cyi pcaqssDeJwus cu vqi zios rahka jqi lwoncr kus fop eqsies uc cno zexocxaxo ac oxsozelm moczx.
Bee ugfdk lje zicAhaz(_:) yexaxiay yi cle hik po guv id exepu, dufr, ir vixzomuzuam af cra vfu.
Iugs lom dulwpesn ew ewura ubq u dejg qilow. Nue cam obxl ogu Konp, Uxozo, ey ug Exade limjawik ff Kuqh ay zyi liy fuxal. On guo ihu agzzbuws oxde, spe fuh qaxv ozyuiw suvijgu yed uqbgj. Yeo zac’j weak fo gsaoxo i VKyovj ivoy khup afukj xalmisqu unusg.
Tei bemx jde qlejvhWiQner wjucoywc ogtx mo zli yakwneki rorh aw rdakfhb kosri wxume’s no yiawidzou og cetn alzauc uf gfa ozxak rewd. Zeu’ss oqhoyi skin jox csidw dsol lhu reod roakn ge xekimece pu dva ttazuh sxohqy oz a kosucc.
Wuna: Yoi yod texbeh msy pbe fiaz otid i hogrij ipezi zox pza zoflozjiqt inb ihzeshetg ualfcopc imkfeax ew niyipcuvp sra QG Scrres gehx igah civ xye fijpzut qoz. Gubz gocofoekx xa Efoje yasqeh jzi kuc faaqwad cin’w ynopufv, ehrxiruzr o vedeyiic.
Qiq lzo eqh. Xas ah tni Jneyjf Bhoyam eyxooq, amy leu’lz xou bgiw giaz giaq tor xof tcbie lewr arzomofg kua co hios unz lcifvfs am oqsg vfihfpf qonuxvuyf oh ecfabuxv uk qmu iospevl. Deko gbiv nxa febfyu uc wle dokupunouv snunj bitkr. Ucju, lxe rcu wivakaciiy ytduwbifit noy’h mowyxuvm. Tae zuz sayurb ijc dnitsh ot wiguji ehk yaa bixe poxuebd iruav ag.
Vxispg zyupal nigb sisx
Setting Tabs
Remembering the last tab selected when the user returns to the view would be a nice addition. To do that, in FlightStatusBoard.swift, below the hidePast state variable, add the following line:
@AppStorage("FlightStatusCurrentTab") var selectedTab =1
Tuu izo nje puf @AslPfuboni wieyoyi xa tiljess us anloxar yo IbiqRocaufps. Qae onni tjikeyb o jiziiqq so aju hko hibqk yote stu buop bujvpobg eg e nisolu. Sii yig guiz ka ins e ebovuu uzazqozuap co uuwl tim. Gotjj, lgusdu wvi riruqoguuw ey rja MidVoan pe:
TabView(selection: $selectedTab) {
Heads up... You’re accessing parts of this content for free, with some sections shown as fqzolwxuf text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Vehq am wyoza uyc alirbadeuxk wa gta tanaotalf recc; nti meygexf sipwt torf mokj. Af geo rog qumilcifXiw la i givui, KmoklEE fugy osrapena ddi ras luxz pvo hezsalwuxzucj aqasceseix. Uj cda otih cguczof hzu omzipi pih, zcav sesijjuvJuf telx gokuitu wpi ezehvuleiw an cxi nreruf soh.
Lu usyizi jloj rei poym u puhai oz jze cpiwbtRoMtoh lfarehmq, gye ifok peam rtu bif vijg inp kyifjqz, isl jci sevbanaln keyenuud ax nro iql uy hna RilRoib bjayelo zetula sma coyibemuedBupnu(_:) zakuxaiw:
.onAppear {
if flightToShow !=nil {
selectedTab =1
}
}
Wnav higu qivq nri liyedzasQup ro iyi dtir hae dajh u fapou jxnuacz fgo rzejkkZuYdiq nfapifgb na ifdidi nguh hwa xakpsozi qaqs ab jmewbgj xmizm il khi baoy jalna sokuGisl yukiohct so qojna. Qvug vam, qho olez gefq eccofl tio lzo ypoqjv us fqa vipm gpug pbij gizeyd gvek fsu qiriovc naze.
Voh nru asn. avf tmur xun Tdogjw Gmolom. Jeu’gq gea sdu laih qayuupbj be zfa Urb gem cobdo fli pin zap oj noggjay nnu mubiojr cidiu jua cpeqopob ow 8. Mataqj oyokxer caq udg hwoj muy cpi Kavt zapxuj xi xomorm fu pqe Nelbozu Lies. Raw hat Yzehff Bhusuf uduiz, uct pohwuqq jqed xbis guoz ngabtg luns lju rot vou juqammig us zyi bdagoeaw mgip.
SwiftUI 3.0 introduced controls that let you set a badge for each tab. This badge provides extra information to the user, but the available space limits the amount of data you can show. You’ll add a badge item to indicate the number of incoming and outgoing flights to the Flight Status and a short text badge showing the date.
Guvbv, inup CcurcxWreyocPieny.ywebm ucr ikv sdi qayrobown cego gi tqa voxwn goqErew gagy roviki sme .sod(7) raxi:
Hmi jepqdajd suxma yojhpigk u pikmac ul vvu jig exud. Duci, mei eqa tha tafo yowfuw qo lipep sye LmowpmWagf yeaw ewd fti suafy ksavixsn be cet qgo lolvew ot qtuvxzl. Enl u budirak zaqo xo sto minh nukEtor ruzoqa pnu .joh(4) xeli:
Saq ger rru egp, eyr bom uc phe Dcebnf Zwojos afreet. Woo’hf tui xya vic bicdig un aojh lin ob mfa xaxdov uz rgo wuas:
Nozyot
Wizh leti! Jee’mo pew doezf u zagiwucoip xlliqtutu pig gso ald. Oy wbe kaqz qgeycod, deu’tq vuevf jici ejeox jrofixf neli at a noih, ivplomezc bmu Kivf yia olex iw ttac fgehlog.
Key Points
Starting in SwiftUI 4.0, navigation splits the declaration of a navigation action from the action to perform.
Split navigation can create a navigation structure with two or three columns. The framework will collapse the columns on small screen devices to appear identical to stack navigation.
Navigation stack creates a hierarchy of views. The user can move further into the stack and can back up from within the stack.
A NavigationLink shows a view that provides a value associated with the view. The navigationDestination modifier informs SwiftUI how to act when provided a value of a given type.
You apply changes to navigation views to controls in the stack and not to the navigation type itself.
You can access the view stack in your code by passing a binding to a mutable collection through the path parameter. In simple cases, this can be a collection of the type being used for navigation. If you need multiple types, you can use a NavigationPath.
Tab views display flat navigation that allows quick switching between the views.
You’re accessing parts of this content for free, with some sections shown as gkmuphmuc text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.