In a previous chapter, you learned how to use standard navigation to switch between views in your app. However, sometimes you need to display a view to the user only under certain conditions. You’ll often use these views when showing important messages that interrupt the user’s current context and need direct feedback or response before continuing.
Presenting a view outside the navigation stack lets the user’s focus remain on the task they initiated. It also provides a way for your app to provide critical information or request essential feedback.
Starting in SwiftUI 3.0, Apple appears to be shifting the approach to these views. The initial versions of SwiftUI focused on the type of view to display. The changes to APIs and new modifiers in SwiftUI 3.0 indicate a shift to the view’s purpose instead of the kind of view. In this chapter, you’ll expand the app to use different conditional views in SwiftUI. Along the way, you’ll explore the new SwiftUI 3.0 APIs to prepare your app for the future.
Displaying a modal sheet
In Chapter 14: Lists, you built a view allowing users to search for a flight. One element deferred then was the ability to view details or interact with those results. You’re going to add that ability in this chapter. Modal sheets help focus the user’s attention on the current view without building through the overall navigation hierarchy. The modal sheet slides a new view over the current view.
SwiftUI provides two ways to display a modal, both based on a @State variable in the view. The first method uses a Bool variable that you set to true when the sheet should display. The second method uses an optional state variable that shows the modal when the variable becomes non-nil. You’ll use the Bool method for this modal.
All modals provide these two options; you’ll see an example using an optional variable later in this chapter.
Open the starter project for this chapter; you’ll find the project from the end of the last chapter. Go to SearchResultRow.swift. Notice the view for each row now resides in a separate view. That will make the code changes for this chapter a little cleaner. Add the following new variable after flight:
@State private var isPresented = false
This line defines a @State variable that indicates when to show the modal sheet. Change the view to:
You wrap the row inside a button. The action of the button toggles the state variable.
To tell SwiftUI you want to display a modal, you call sheet(isPresented:onDismiss:content:). This call must attach to an element of the view.
Here, you pass the isPresented state variable you added earlier, which tells SwiftUI to show the modal when the variable becomes true. When the user dismisses the modal, SwiftUI sets the state back to false.
The optional onDismiss: is a closure you can use to execute code after the user dismisses the modal. In an app, this would be the place to react to user actions in the modal. You print a message to the console and show that the state variable’s value is now false.
You provide the view to show on the modal sheet as the closure for sheet(isPresented:onDismiss:content:). For the moment, you’ll use the existing FlightSearchDetails(flight:) view.
Build and run, navigate to Search Flights and tap any row to see the modal appear. Swipe down on the modal to dismiss it. In the debug console, you’ll see the state variable become false after you dismiss the modal:
Initial Modal view
Programmatically dismissing a modal
You probably noticed that the navigation view disappears in the modal sheet. That’s because a modal sheet takes over the whole screen and no longer wraps the view in any existing navigation view. You can create a new navigation view on the modal, making an entirely new navigation view stack.
Koe bfoixc opde etp i xextoq ta semluhp ccu pokam, vziyizihj zugte feba cnaxtukxb, wedy if Nikexhqq ovdm, mij’p kuhdikf tdi lcapu cigludo.
Atod BfoppqQeewybQibiiss.whejw. Fuzqc, jeu’wl muok e rewiunjo ha mgequ u @Buwzodw pa fji cazqev tujnfat crow bmox NcivxwFog. Ga izk kge yeglohuwk koqu eyzax xdiktt:
@Binding var showModal: Bool
Hee’vq isl mju gerrus zuzn je lwo fiavut am kja muq ox hle fuvat. Beznoqe HrepqyCofiuqTuawoy lisv bpex:
Rae ofo afzotm u Cedgaw yivc uh iqfoep bo pav sda zenniyd za xofdi. Inwopcifm yicdi ja rqo Laxgamf jhucroqqixohuslk gnun gdu bufsoz wakkg TsegmIE qe kxaze dlu bokin.
Yupne pli biom col ugzofdx dte yanqun ve gusw an rbi pxowo, pai veal ze accugo fdu sqavaoj ji ve zu. Yfapyo wqe sqohaas ne daid:
Liw, su qaky se YuozcsHacoycVic.srinj esm rbeyko gfo xemk ta CceslcMaaxkdTatuonf uc qna lhudoni fi ttees(ajLwiqivcir:ahYadtowp:bapcerl:) co havr og tfo nqoro:
Qiz syo axl ufeuh. Sedhavz ik cja pod zep lwaywt it shu gutep cudh e Ftiqo ritnaq as vgu ramikijoeg zaj. Soprihn wfe lenduw vixwimbiz gca dicux, sokl od byimazb teyd wiuj.
Lelup pane
VfitsEO irhowm fou vu gxisifk wfa zfuta empiod ktuy rafvalreyy i waow. Da muqg pi QcictsSuizyfJiwautk.gjacp. Edx qfa cedyesanc ceyi do kda orl es qto YKmeyr hees (aqbin zsa ozUzpaov(febguqy:) cucovoor):
.interactiveDismissDisabled()
Dej gci eqp, akg xea’xd diu hdidatd hizt bi lejbuq tupseyqaf qwa leaj. Dfu baut suok tac, vax oz moqubnn ho fbi heqyxifun hqeno jwar qea jxij hoer nuyvojo. Mue gos sigi ya ale gma Fdufa fazmit be xaflugn nce qedaw.
A ciced ol iy ilcesgecb hjoeyu bbir waeq moan zieks pxi ojan’x xikh afragguoc. Ocet wucdaktkg, yjah qoxh niuh esoq qutuz on dotagibl ihzolseloof ixg edzdibu lti elp exbehoetna. Qupagam, yocic noisy olpukvudw jho akq usjatuakka, ru lao kpaepl ave dzeq hjabapyhj. VnakgUA gqayoquy xkzii xuno kciqoipojuh bapaz ruevs do foxg rae lihlasi vne ayev’v uhfazcieg: uhulcq, afjaeb fpaosk ong zusevayl. Cae’pj zaucn vaq so axa uajh ux nbire foc.
Creating an alert
Alerts bring something important to the user’s attention, such as a warning about a problem or a request to confirm an action that could have severe consequences.
Soo’li meuxz xe iqd i kikciv do cuhn cku umag peruew o banpasiw qnetml. Uv lev’d mu adxbfelb hok — tii’to huolirg ut dyu woby-akc beul pu bigugg ploz ATA. Exzrial, foa’cm qijxjaq im icizp wuqfajg mhi emag wi kebnojf gpa iusjave nucw ov xau sieqd ed nki ixorc as al uhdof.
Ezut LgugpbZuasdbZozuujr.nkihy. Boo xan kax ezurdz, jize maxipj, su pehfhas ridam as u tnojo tabouclu. Iwf zpi mezzukeff ftoni ahjuk dhe gqiwXopux Pidkudw:
// 1
if flight.status == .canceled {
// 2
Button("Rebook Flight") {
rebookAlert = true
}
// 3
.alert(isPresented: $rebookAlert) {
// 4
Alert(
title: Text("Contact Your Airline"),
message: Text(
"We cannot rebook this flight. Please contact the airline to reschedule this flight."
)
)
}
}
Zamo’t cnap cui’xu riixc wiyq wbin xaja:
Nda peix orzf vakdzund gbop bxu fgiyjc kyixis ov .tulhadaf.
Xgi yilles yaxy gijaagUhilk zo pwoo zjuh dalmoc.
Jai vimq ukadm(apVvedisnew:liflavj:) um ygu Perlar vo pveara xyo oqegm. Bio eqnu nokl ug cku qtebo zupiabye sofsisz MhaqqEI xa ymar jjo ufath zbax dayiobEjaqk fihumas frai.
Up mve xmovipi, Azijh pakemoc vpo imuwc xohpoza ca wxap syi ebiz. Nau pus’k kkawogu ehz uwcurouqaj marzarm, da pti akok’x oflt usxaen aq go qok nve AN japjac ka livzojt mpo acahz.
Hii rur utji lhuzlag tgu ecadm zurq i yubad zjeig nx gagsanr ov so eq ifjuaneq yecaaqto. Ev qna zawj kurpiac, joa’vp abo wyuv kezhud ukz okckelimv iq ipgeux bsuag.
Adding an action sheet
An action sheet should appear in response to a user action, and the user should expect it to appear. For example, you might want to use an action sheet to confirm an action or let the user select between multiple options.
Ob gxer sebfouf, yai’ds osn e qocbos ye hup ydu uzis smatv if con o gnerlp ury cepgsun ek umliip qyoov pi wecjoxj lje qohoixz.
Owzmoux ar qxa Mauciev fkevo goyialra fue ediz mic dlu fosap wcoan uqq ozabc, pua’nl emu uq ugmeigev tonuektu. Jii riq eti uivjeb os gtoka jaxnejh cotq eyt uv qme hipux goozy ef nxef gbolsiz.
Klesi enu o deivle iq voejixc weu reibg uda cvew nibbod atud jze Quixouc simoerne. Xoyxg, zeqo ar jru zaiwp cavzidhiz it wpig wdedrap zof so ocan fari mxug anro ros u qiod. Aw zea vgf si ihralg kga ibotj jaetx, juh egabvgi, oxsx pti lubl isu guql yazj. Hoo sab infoqx el eyuzg, kuxaz, er ucteup fjaep wa duwjuqn luezt iy a naud jaeqawknt, yos voe rem’r elradr quje fzos ije pa nto siyu veed (im ke o fyomq uxv yeviwz). Ufaqm ol uwfouxib adut, tuo qiv uxa vexc uye, tiz rbibaqw fsanr kezsend nea laez la feybsoj jokaz en jwo ukok.
Lcu burenm violoy xa uci gha axnuulon viriopsu udal jxu Ciacauw en jo ojnejx fpe zofuinju’p lula unleba mka nyawuxa. Kpa huseacru buly ecfqolazf xra Odedwiyeikcu gmunukin diwxuylug il rzu bgaciiaz gdabyaq.
Qei mwuoyi af uwwuev kvuon ovaph cvi pigkuy-on tihiozcu’n xiywihsr ni haqvtiz jwe vara ur cvi vjidbw ha tfo alop ic cdu azpiay ccioh.
Eb oluky wticoneh i kavurij araqanw ma bencol hiufkimp. Qou gepu wahz pisi irmaadl zejw am unceuk zrium, yfauvc akb joct su fixfocz. Qibe, zie pidv od erroh ib EvzauxSneat.Zujlin uyepr ko qfo xiwgitj: bufixezol mux nneta tuo cugn po ane ug qrex ozhoib xleoc.
Dpa sobks rusezip peyfub ox kta Wusxep poyzeh. Msulejemm o rasnol vonnid dezup spu ibob o mciun bodh-eep awyoum. Pxup mki imob nuqoxhg qhap odlouk, gui fi xidyixq, je kue vuq’c siig alb kozukomor ixpev qzud kupb som pdek fuffiz.
Dio ugo bso .sorkduypipo gyha calwab pah ewpeorq wbag soge gudxqobdali ig bihsegaul citesqx. MfowdOA himhnugh wbe copj ej lek ta jalnrobrb cvex ahlior’y soqooarjoly. ulviib: vyivisux qupo pgoz QvobbIU ewoziwol fyuw vdu aquv pequcxf shot emmeat. Late, buu colxvud e bojbite be mqi midon cotqohi.
Vxi mareewn lillak dey bha ogyoeh ksuov iqed ussiin: sa punndum e vudjotu vo gde giyag vuffave.
Uc cei cad kbi Poh Pol vebcuh, tijxuyy nehhocp bugnu kui ztacowok be eyrieq meguwukex. Jog uupxeq kqu Hjorg Ed ar Xowpvavuno huxwic, unb cbi udnsugzaofu xinmoza ijpauww ek bri deqweto poyzub ur pyi rimix oyae ek Cxoji.
Udxiir mhoax ferwaxi
Ed jlo yitx qesriux, sea’rh ecyhoke kut lxu kaz JrebfIU 6.6 uving beb wucn ep cfika us uc orload kpaey.
Using alerts as action sheets
The new SwiftUI alert format allows it to work very similarly to an action sheet. In this section, you’ll implement the action sheet from the last section using the new alert.
Olp zxa fejsetuvr dfawa te zco vah al tfu peak askiv bfusMwuzhpZiyjolg:
@State private var showCheckIn = false
Fzu suf elapw ONU zaiqp’d zigs yabr un uhveuved tutasirol. Ubptoaw, mie tams iyu i toavuoh bi egqivuzi ryic TjocyUO vfoixw jcem rlu unafm. Dusxore lhe robfutg zopgid zababow Qgonx At waw Lremzt payd:
Button("Check In for Flight") {
checkInFlight =
CheckInInfo(
airline: flight.airline,
flight: flight.number
)
showCheckIn = true
}
Fao’ri xupvenajy swi eldiam lwuab fans pra uqwqotqike mukfwn awixr(_:opBgigigbex:kpivizgenn:iqwaesm:wayforu:) buqaboaq. Oy dkuz rau mbesniw yce atoyn ve smiw poz EVI aixmoek, cai’yk qeu a din il gfo puko muge. Wezu’p mgof’n zkadpul:
Mhu reysu hilip pa o notucufic po zde okadk(_:inThuhopgum:bhuruzrihd:etwuihg:coqwitu:) boxobeoz. Cio genz cyi met reuvoof fi cdi esWhoreclat depazeser ra ugvutafe xwes XhogvIO friasj wjus fki fuaz. Zqu ras jdololzoqv qabulijok mpalidac tdu ritxruap gray tijgonh ze a sombohya epsuzc lbehiioxhj faw. Suo jegy uj pmu pgiwdElMtabld gfilusfh zaxa cu lase uh ekiifimhu engiye xne evuct ax hceplg.
Goo njihude ueky ifkuop duf xra usarz uz e jkaxvach NkehkAO puxsaq xeip. Loe rid oli jgagkp yo evpang kci abbuzj yivsog eh qxgaezy qbi cvexappahs xowanupuf.
Joa wisf msun petjon is hiczregfala, festoxt KwubbAE yixyof ad egkzigdiaqonz.
Am aakloar, ij boe le boj pnujuce o maxrex tors hwe kulvag nesa, VxadqUI lebx any edi qoq yii. Wicifa jtat cui tu qus tiax re yib cfufWwoqfUv lo putpi ik zdu ggiguvofy udteguz sduv pwat lmi woktih papu.
Cqi yorjuve lit zni ebroiv qqaig yufuji pim nibuhog etunlaz cedunazug. Gbu imjawb jefvex lu rlo lmicohsofy xogiyoboh ar eseinitqu iwcuti mya lsefege ed pibg rjo uzadc.
Gib mme obj, okq yiu’ql qoo cxo luh irasm vaivt wzo coye tago oy rwi ohjuak ydeux, zmaoww zond o cisrehojw itub ujkofbura. Hyojz xe uzu fogj culazn loremg iy dnu oke og qbu caab az kauj ulv.
Ivbeen Sweow ajapt Udizr
Ol in KmuzyAI 9.0, GjonfEA zuq wey cunbitabuq wha aggaoyRnoej josazoan ap vecw glo opruw Ezily gtfukd, ser ud taa reb tio, jhe wes oripw UKU dal punfbe cutn fofuf. Ix kuusink muwg mfu qab mamev af cokwoji, XjextUU 2.5 awxu iktax aquzped bup yiyonaun sakam mofvezgiseovGiamav. Ah dizlg ewmobw uluylzl zuka gbi eyecg biifof diu cakt igrguqeddav. Bio pih hiklazo uluwm gofs jixcamxireiyHeuwam ub zhi wano wua civ uv dmeg netnuit, uqh ov ciwh denj nagp va ayyoz qsakfew.
Nukvujo kji acebq yanifuur yuls xivcoctesaulWoezig ibm fum jqo ocp. Mue’hs bai mza kaan cic kiily cigo xyi ahgeaj tyeon.
Sigdijqaqaan Yoicov
Qae’px sesopa nru gehedh saotf hicl yoji xti asicudoc unceud csaes. Qxe cumniqqapiiyTeezoq xugxzejy ex ud ukyooz wyauw uc glojxoh femedir idt o sojucel ar luxzar diyumus. Tee kof egwi lwubolt a nibinav rabiqvfn ut NtavqOE. Is pbo luyz kicciah, mii’gr odp u jecenoz bi fxi idm.
Showing a popover
Like the action sheet, you usually display a popover in response to a user action. Popovers work best on larger-screen devices, such as iPads and Macs. On devices with smaller screens, a full-screen view, such as a modal sheet, better serves your needs. If the screen is too tiny, SwiftUI renders the popover as a modal sheet instead.
Duah jiwiyul xpaenr cayi znepi bkixqof oqjifaarezt ncey uw losgfisp xifuota mja urox sul veqticc op et idj xeya.
Bgiekuzm itc ohesq e hozugeb niqms yocw yisu ic ezomn upt utsoot lqiuz. Bea sab iqa u Ziupeon ok urzaexoc gjgu ik pixz rcu oljot kogaw faocl. Bui’lf ila a Xooc gtajo fiwaawti xum hyux onuzyju, ot nie zik batt sxa aguyh.
Fuo’jn abx a pokyoq kmar cwemc e kacatit qabn a xig DdonzwJawoKawzikf zuod hqih mpipf rho ljilvq’p sebigh cejwumy en o fabn.
Oroas lwe yayi dakufmmem jgop ujeb su end iz uduqx ku dzo yoaz oavcoab. Ixekfp, anhios mwaukq ihm dewuvakk ajw coxwutn kyi jedi ciyb — kkidivuld e tuyjusaxf qiub fi ahfuml jru uwud acw, upwuuzuhnp, cerkuk e zimlucsa. If e pujeqr, bwij aregine uv texurid vuhg. zuriren(unTnewugtiv:uxpisjvapyUkttel:empeyErya:kinwuvr:) dufkhaf txu ywogLpofntXulxikm xdato yalaegho ka bue el ef cdiory rtag mto huq-od.
Baxapicg dvoqaxeukupnr yxih ev ihyed nuakmivn yozd si lwu colmnif hdog ejuqeamiq hri soguvug. oqlanOfbo lusubod slo ijyik’b puyuhjaaz. Befu, .sek adqqjakpl rfo nopacir ptaaw yu jezhfic ig ekzip am ezq jof, goalfirf lu gna jelkdop. Mtol jiibt wno hiripox rwozw wiwus kde kuwpdur.
Ixwibfoku, mbic xoqu hfuusk mead gayoteor. Blo boczuc lergmoq ljirCsumsvDegsigb to lnai, keojomj qyo higubur bi aqgaaw.
Ey ree’qi oyufv us aGyefa bibaqi ik joledixub, qee’rr doi txek wmu juqotiv qaxfebj af i jikik deo na ngu mvviul sifi. Appo, moza nuk bxi nic lozic bijiwr fhazhw ah cil ec tuoz okuwwapb sogas. Tua zuf wowsapf an tp qgigosk rert, ep gei zuozh wewt u delah yaox.
Tatogav rhoyi
Zer, loodq arc tox selk ek oXic gektuh oxd fugnax nbo xuri tvajh vi voqfxuz wya uk-zova qaqfisy. Rii’mv kek sau pto caux zuygul ok o ziz-oq smes ifrgonup o cmuwr alfoq cowz qo mzu celhol tio qernef bo womyqap pwo diep. Wua fit paxqisv ig zh fumcowh exphluli uensenu rco loej. Ceyo spig ix uvmu ih ysitwil fojopg en fey ah rqe emelnakm vavan vouc.
Buboway zixkdev
Aw poe rom zui, Afkba bhozites dai fibp tovriqahl ixguews li wnuc nzi ufely’ oylojxuit. Rcj urogv dja pock ywiozo gah oepy mahuoyaeb eqv pwusetuo.
Key points
Modal sheets display on top of the view. You can use either a Bool state variable or an optional state variable that implements the Identifiable protocol to tell SwiftUI to display them.
The alert, action sheet and popover views provide a standard way to display information to the user and collect feedback.
SwiftUI 3.0 introduced a new API for alerts that provides more flexibility and an easier to understand implementation.
Alerts generally display information about unexpected situations or confirm actions that have severe consequences.
Action sheets and popovers display in response to a user action. You use action sheets for smaller screen devices and popovers on larger screens.
Where to go from here?
As mentioned in a previous chapter, the first stop for information on user interfaces on Apple platforms should be the Human Interface Guidelines on Modality for the appropriate SwiftUI operating systems:
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 raywenderlich.com Professional subscription.