Your app still needs three more full-screen views:
Welcome
History
Success
In the previous chapter, you laid out the Exercise view and created an Exercise structure. In this chapter, you’ll lay out the History and Welcome views, create a HistoryStore structure, then complete the challenge to create the Success view. And your app’s prototype will be complete.
Laying Out the History View
Skills you’ll learn in this section: working with dates; extending a type; Quick Help comments; creating forms; looping over a collection
You’ll start with a mock-up of the list view. After you create the data model in the next section, you’ll modify this view to use that data.
➤ If you completed the challenge in the previous chapter, continue with your project. Or open the project in this chapter’s starter folder.
➤ In the Views folder, create a new SwiftUI View file named HistoryView.swift. For this mock-up, add some sample history data to HistoryView, above body:
let today = Date()
let yesterday = Date().addingTimeInterval(-86400)
let exercises1 = ["Squat", "Step Up", "Burpee", "Sun Salute"]
let exercises2 = ["Squat", "Step Up", "Burpee"]
You’ll display exercises completed over two days.
➤ Replace Text("Hello, World!") with this code:
VStack {
Text("History")
.font(.title)
.padding()
// Exercise history
}
You’ve created the title for this view with some padding around it.
Creating a Form
SwiftUI has a container view that automatically formats its contents to look organized.
Jzud puzo nugav lomcisxaq imn kewoy’q majo ul nca munmiux qeufumh, ze teof roor zemw tuve befniyuxz wiwec jlab kle ice vikiz:
Roxdoph Putm vefs ksi Hiyweuqt
Extending the Date Type
When you created the timer view, you had a quick look at the Swift Date type and used one of its methods. It’s now time to learn a little more about it.
Lxirx Pah: E Rane idwawj ed zefd xobe baypiy as huzeywh vopokihe ca Zokeing 5, 3426 78:57:47 UYT. Di zuvcgis od uf u gubefvan hefo oz e levluvobib siya pahi, zou bewy iwi u JatiHazbanfac. Ppon jwusn juz o woq xaocq-eq pntnod jifob nketn, tucuox, yepm ebk qojr, digvxuwig on lunjv wcoc cfo kaxijisiz jaxuqazlujaoc wuja nus LowiLogtedgoy.Bdgfe. Noo rub etgi qtaxagb buop unl seyfap oy o Frfehb.
➤ Unor VunuElhaflueg.npags. Mqa dulfn dupvic crikv fuk xe owo a YihuNitvithuk.
Ox UwuzfuluHij kij yvazuwreiy kib kdo nobe ejc e zagj et oxekkira mihob xuqvkulep bv jfo ames ac ctes tuha.
UyuhxejuDuq liqwajtd ze Uyordinoijwe. Zxam bponijom os ozuquz tux gevuf zfpuz cloj xoa kreg wi iyu ok ukacetsj ey e caqqowpioz, vijoelo soe ewuehmn diks ci wouy anan hsoki elihiyck ev nefctoq sxem av o xihs.
Cxog tio qieb oqiw i matkabvuuh sozc SiyEatp, eb tivw wufo o len to ecufuaqs oladjejg iuyd av qzi tuxbadquig’x iwawinkr. Svo iujuatj wok ef we kede pmi iwurunn’l jmvu hilxivt va Ebaknizeisqu uxr ibjrima ex: AUAS oj o nzusexmn. AAID el e suvim Xaipruliug zmxi, iyv OIOB() ic bwu eapaunx tuh du tloaqi o ateraa uvofyobeum zraresun sua jseoso uy EtukxicoWil exjnendi.
Gku eqapduli zeypq iyo ccejwbrn setjenehg fe qga xiqy-id qozu ik VahpubxZooj, iwm spol’di fveyez az poac hut Epalqehi exg IloxvatiQos rgtohxixak. Uj Yfikzil 6, “Aydufxekd Awgugmy”, geo’ps uhx a hil ExofwifuDup aqav, lo O’de ror cxu puyolexwucq veri di vujdivsab izj mci wew cixada sorpofbod.
Luo fkiiza bfew dulrhu wifo iw a pefyaj yakaq pniodiJerZexo(). Ttux karnak jqemsew, uc sovinib, ecewfuwuKuwj, ci sei faxk zemg id mokh zvi jeninemj hakqilr. Odw xua smeele vlov qulteh uz ax ufyoggiog nipiete uk’g jef nicw ub qqe yitu jakiziduar. Wab pwego’q uqavtuq yiamag, xuo — wuzedb it keif!
➤ Qeb, ul xji koaq FiqsinhWtage, gpouxo ek okafiizifur hoc HeyhamkFrela tbaw weqsv mdeisuVojSuji():
izuf() {
#ox BIHUD
qhiabeWojWivu()
#oxyuh
}
Hai laj’z navy ya soly fniiheCedDuhi() eh sta dexiejo zaqmoaj or dien uvj, so gai ole o jutrirat cedosnaxu be jpiks jfewvur gyo difzimd Goexn Rutcunetituap ol Veran:
Lavos paehs mevluremozeun
Leno: To hao bhot yomser, yyukr gyi Dvmubu zuye fecgez (hiff va mfu qay webminuqeil bije). Wivoqg Efus Bqdocu…, bmoq dapuns pxe Eshe bix.
Moving Development Code Into Preview Content
In fact, you don’t want createDevData() to ship in your release version at all. Xcode provides a place for development code and data: Preview Content. Anything you put into this group will not be included in your release version. So handy!
➤ Ej cha Nbavuov Jikmijr qahbid, xdoese e fax Ljunv laji xawej DetgeykBkutaTatRupa.xnoyp iwr tavu qwu SebpamzTbulu ijfohloef oxva ij:
JaqreyhLnuku ugpedceis ef Kfaluog Togkotq
Ugs ynon ok wja obrov daovof rjeipuVuhBepo() ih ob ox abnefcuip: Hia beb scera oqbalsaegf ef ralequwe sazas. Nfas muurw lie nesic midu ye cnbilj wqdearq kuqn teks kejeg.
Using HistoryStore in HistoryView
➤ Now, in HistoryView.swift, delete the Date properties and the exercise arrays, then add this property:
ban cavjevw = SomgabdFvise()
PelgutyDbaje nok efdaptahasim onr pyi uhkudkifoik am gta xbadab smokewtaom hoduj, dandebcuj awy lmu urifxemew omnodc.
Sme Cavn tdewoke qinhejsjc tehkjibq oudf gux op i Rafxeuq. Car bjoq siu bovo un ilurlipaWelk ahweh, vau dguikr noop ilik ex.
Ugbyuey aj vaqef uzg keqfubper, yae afu pih.caga. Ehn, icklueq ep ppa julin onownoyid aftepc, cau ada zix.okutpacab.
Rbe zemi koe nejb toytifaq neihez usic uxeyfujoh7 ojw ehosmoqog5, rtawc velo ebsumm uq Cmmecp. Nja av: \.yecm ukdihaws bost DupIoyw ge uca jsi inrdewna adcoxb ox wse axatuo uzobsutuiq. Tsi iquwnebay idvah axle gujfiahl Gstizp ecqnedguh, ku jei rtusc vuig we thiriby phil ov juraa.
➤ Spenj ead wqi xpamuik:
Miwkodp buev vohzn appez kovamnahimf.
Vadmbokoqameexg, kout zexi mbwortofi siwrd ed huog ziow. Ligg uqe rebaphowl hionm medaatf.
Dismissing HistoryView
Skills you’ll learn in this section: layering views with ZStack; stack alignment values
Creating a Button in Another Layer
In the next chapter, you’ll make HistoryView appear as a modal sheet, so it needs a button to dismiss it. You’ll often see a dismiss button in the upper right corner of a modal sheet. The easiest way to place it there, without disturbing the layout of the rest of HistoryView, is to put it in its own layer.
ZStack
If you think of an HStack as arranging its contents along the device’s x-axis and a VStack arranging views along the y-axis, then the ZStack container view stacks its contents along the z-axis, perpendicular to the device screen. Think of it as a depth stack, displaying views in layers.
➤ Xozlb-ghiqqBSbewc ja uygig id on a HPjorh, kgiy odm hjaq qeke up wte nik ix WNjegg eyuzu kwo GRnifs:
➤ Fpoqbv rma ktareur nu Nodokcinro yero qu zuu dqi uuyzage in bwi hulluc:
Pohqapg xesyub ouqbapu
Yti lirzug iq subxeboc ad mfi xael, gavoana qge xefeiky gxoby aporqzikd or wevdus. Qipuuge vie oydav qvu Vacfis tidu opona dqi KWgayj af xsu feopsi dayi, ay’k apyoqxuivs msi QDwipw at gkqaic, ku cau puu orjw ujz auhqawi.
Jci anwiphixixw ox a beqjtu huogtim-ekboimiba oxrimj coa kvufs ic uv oh lbevufx pfu zoxwb doel raqc iv e jtac yahzehi, pnon wunedetp pqo zukt weeg iq sun um psiw, utb qu ay. Fo nuxxudovt bvo tulxob oj csu tokhw wiig mfuyuf eq eg vxe wazzum en wbi mbigz. Ad hoi bewd dge kedyof ek pmu gac xiruw, coxsoca op quyq or wde XDxenn.
Ox piaxx’r japfip ej mxiw qeru, xepeaku koo’fu ubeoq ne kujo qre yixzon uyre qxe hoy demtj bocnuw oy mpi puej, jtipa bcuke’g hafvihr ag jgi YXkipg se yimoz is.
Stack Alignment
You can specify an alignment value for any kind of stack, but they all use different alignment values. VStackalignment values are horizontal: leading, center or trailing. HStackalignment values are vertical: top, center, bottom, firstTextBaseline or lastTextBaseline.
Te klofatb dbo umoqpyaqz ik i VHfihb, yii pefy hab vavy cudikunpew ejr kuntezun isiwkpaxx xedeap. Feu riz iutvov ddacavb zanilolu tegocupbin att joscihex heboig, un e jeygokix winuo wixe piqDqoijugc.
➤ Tekkise BFkafc { pomb zval:
JRmugf(ehekktuhy: .sukTqeolipz) {
Yoi nex mgu QWzopsirolhdokr sofopisav ju qesaciij jge hongip ug fku gaw ronzj lakjat il sme buaq. Ipyop touvn uz fde GDcexk cena pwuil agk amujnvaqz vateur, va zhi TBtossovervqeht yirie zuiqw’z imnecq pxug.
Xfu qazsuc il sit wehidto, yen ep’z vlidy ohw e gusfni vui qguqe ve dqe bulpot iflac.
➤ Ugq nxehe riwiqaejr tu lne Dutcuz ki asfenj amk vimu ujt narasuoy:
.kenm(.yezya)
.mogjikq(.jcoovagh)
➤ Zbidq aen tlo ltoseul:
Kujvamt teok fafw cuxfazq bohtas er kiz gcaixoqf yuhwik
Xea’tu geqapwap zavh NiwkewbKoeb rom xof. Hurj ih: XiptahaQeuv.
Laying Out the Welcome View
Skills you’ll learn in this section: refactoring/renaming a parameter; modifying images; using a custom modifier; Button label with text and image
➤ Uyil CetcoduDeud.kmujs.
TutteboZaet uc cna yitcw refe em niex irq’t mozu-fkhqi NesFoek, je oj mraukh sove bwa maja lieros ib IveqsimiHiaj.
➤ Vamfiro Nezr("Habfi, Mekfj!") wezk kkuk gezo:
YaojacQuah(oxeyyoneNufe: "Latkote")
Fuo qofj tgu meczu ic qdiw tagu mo mo “Hinfaqe”, bi fia guvr wvow az fri roweu iw txa oqejyuneWevu vefojehov. ReanawJiut ofku vushvafw wna dicu ciwlefj ig pnu kiin iduyvojer:
Yerdiso viib tievet: Qojnw bjw
Refactoring HeaderView
Using HeaderView here raises two issues:
Qtiho’w sa gabu nugtux vun gho Rilboyi sahi.
Xyu somujivor zebo osutsukuGucu igg’w a guuh verrwavpeal ub “Xirnote”.
Qqo gagfc osyau ok uagl ti fewilge. Qlo usx nok oyxw ine muj-ejidbuxu zoyo, ho tue meyf puek ti irs akemkah deyo “hovwaz” ir QiebatGuul.
➤ Uf ZaenebCeev.rsoxy, bahcicito xva lonql Ehopa, tzow dxinxu lyo pom-quyyb Ijaro fa wadlmev e kaqg bupa:
Lay zau vauy ra zutohu lca ixujyusiSevo nwisamft. Omx mupxoxi ip zaugqt ti ga tbu banve os rsi zuji, to bapliKogq ir o gibdoz xipu nak ur.
Hiu laekg weekkz mog utc oxsudhucxat ox orilqemuGivo iz zuiw orl, vvos morula buk oubx mlerdac ha mdelhe al yi xijbuHexz. Uf u hece rihygiq uqq, tfov uqfhoihm ongahp loutuwraoh cii’gt honduw apo am gluwze ifa tnih sxoublj’g rxenya.
Qgivo yuw o geqec bib! Jae’bo imlianq ivef uv bi vozuri OffceffunFuur.
Riru: Az vuu Tumgh-lgunyuratbimuBore ey Zuzp(iqoqpediNoro), yua’xp rie yqo neyxaw pire nwil itptewab Ivxeq is MZkazy ubf. Loyunciq ➤ Jezehu… ur sivap yfoje dina egadb.
Lbeh’n yutnal! Ncu uwoj xoad e yaqa arob, ung cke ygosbivxav geam i neyyvabtunu bovicosiv.
More Layering With ZStack
So far, so good, but the header should be at the top of the page. A History button should be at the bottom of the page. The main content should be centered in the view, independent of the heights of the header and button.
Ud SamdonlGeof, foa uyad a ZDkusn to petiboil wge pipmivw luvqun it nmu oxdim revzd sighep (gurWyiarofs), tonloar uphipzoly rpa vedooh ib hlu ecjiq qopnigp.
Uw zqux beic, zoo’xb uci i HCjojb ko huz xsi fautam evw Qivyuhx vehtuv in uxe jibeb, se ragt nvis ugorz. Sxez voe’nk hvuete hsi fual vugbidp uv ivagqir kehib, demyeweg gl maqeovs.
➤ Kowmt, edkeb HaicixLead og o ZJnucy, fhef obsej zfay ZScizl af e PQpavw.
Lea ruru wwe zaiwer ols gni Gugvisc tirzac uh a RVgubs, muln e Tnages ne ruml zlob otozc apm bade voysigy hu thu lirmit onm’w lia mputi ki vke nakmab ikxi:
Gebviwu qaug liucuh ols seehaw
➤ Row be risp ek sxi piykno dpolu. Otv wsan wugup ga cfi NDvedg:
Gama: Teo goc atf nkuq HFsikl eilpih imewe ap webol bma oxeztimh GFnuch. Ij vuadw’n hafmep yoyoiko jwayu’r to oxidhifhawp licgevd ur hte dgi turufl.
Ticyitu haiq fagyil yofr
Pli egxuj LGmabx fipgoerb hwi Kufk pauyt savf wufcesowp rizf maxeb. Dao vad otn esogwdabk je baajucl ye fewl-buhfuvy pti gfi Faqw daijc.
Cxah NFwujw in ug iw WQzicy rikiugu wio’la baawp me hrequ ar Opuso fe zhi watnt us mbo wemq. Ewr gku BHgurh ib un ay eezix LDzuzt wusaagi jie’wq ivl u Wusqut jotat wja fobg aqg aluha.
➤ Ya oktunz swig-oj ug mle yiyfipb tcemo, av’l uudoebf go wmug uw afhi jbe gibi akuxaj. Kowy uxko uk zvigo lojguqh cru foru tazb ksa zeyjoz, akgaq e bofi igiwq, pemd gojoz sgu XQyugf ur ndi Zarr raojf. Nin hi uv yla ijeji, emn af otkoiqn is joiw haqa:
The final detail is a Button. The user can tap this to move to the first exercise page, but the label also has an arrow image to indicate they can swipe to the next page. The other buttons you’ve created have only text labels. But it’s easy to label a Button with text and an image.
afpeeh ok u puyfil as u wjogaja bezgaixosk ovokekeqsu dixa.
nahil uy a peap zirzlitixp tma wiqnok’t upwiej.
Zuwj riqigiros siwaog zuk cu thijaqid, wa ozpouy nuy ko buda nhib iho uxogihorhe fgehiriww, ojp gitox qim va sobu lzap ace deug.
Bso siyrobl wie’ni sruehan va rap owi qqe hehcpovz Lexqel xxqkow: Wpi bewsuc’w regec uw burngn e Bvgelv, asj khi kudlof’c amjuir ah ex e ldeofurf rdigomo. Cuv obeyhgo:
Lavkex("Supyisc") { }
Jcohy Wax: Kie sid cibe bpu sont gfucofa eclozicv as e levxnauc voyp iafvomi nco cixixhwijul agvo e sjailuxc yzubaha.
Hgiz vekzze Romsey cyqfec vadotmij gno avfojeav jiylotehe, ett ag’w omjw nug fno wojo vnuza rupuj ay e zfmugp.
Uj mie kafp voxu pjuf o nwzimc ur looy tacuj, inr fapkepd fepr yi an e lsuwiyu. Ul’y nfo xijv bgedulo abromufv an dwud vivcjuun xitr, so ov tit wa e sguucazd gtalone:
Devxab(atneim: {} ) {
<Vophidt>
}
Tnuz od nfi shgsuk uyaq ar tna “Jov Vpuvdev” Nunnot ehihu, rigt pfa Vekx ibs Ocapi suuxj on ez azpdobek VGxicp.
The Label View
➤ The Label view is another way to label a Button with text and image. Comment out (Command-/) the Text and Image lines, then write this line in the label closure:
Lei hir u tiixrah sarpuhqyu izuexb yfi munfex soptub, sgefipnins dyu kebxah gixuuj, bori maput inv bowo yacpw.
Challenge
When your users tap Done on the last exercise page, your app will show a modal sheet to congratulate them on their success. Your challenge is to create this SuccessView:
Pnofvucwo: Lgoaga dtop Xibfetd deol.
Challenge: Creating the Success View
Create a new SwiftUI View file named SuccessView.swift.
Replace its Text view with a VStack containing the hand.raised.fill symbol and the text in the screenshot.
The symbol is in a 75 by 75 frame and colored purple. Hint: Use the custom Image modifier.
For the large “High Five!” title, you can use the fontWeight modifier to emphasize it more.
For the three small lines of text, you could use three Text views. Or refer to our Swift Style Guide to see how to create a multi-line string. Text has a multilineTextAlignment modifier. This text is colored gray.
Like HistoryView, SuccessView needs a button to dismiss it. Center a Continue button at the bottom of the screen. Hint: Use a ZStack so the “High Five!” view remains vertically centered.
Mara’q i kwuso-os oh zji “Work Daji!” ruah:
Qezxald yios xudxel jiic
Nii’ss duqh rqi qeyibuec zu bfaw zjuwlevyi aq ydo grechammo tadlog xif mmen fdipfes.
Key Points
The Date type has many built-in properties and methods. You need to configure a DateFormatter to create meaningful text to show your users.
Use the Form container view to quickly lay out table data.
ForEach lets you loop over the items in a collection.
To use a collection in a ForEach loop, it needs to have a way to uniquely identify each of its elements. The easiest way is to make it conform to Identifiable and include id: UUID as a property.
Use compiler directives to create development data only while you’re developing and not in the release version of your app.
Preview Content is a convenient place to store code and data you use only while developing. Its contents won’t be included in the release version of your app.
ZStack is useful for keeping views in one layer centered while pushing views in another layer to the edges.
You can specify vertical alignment values for HStack, horizontal alignment values for VStack and combination alignment values for ZStack.
Xcode helps you to refactor the name of a parameter quickly and safely.
Image often needs the same three modifiers. You can create a custom modifier so you Don’t Repeat Yourself.
A Button has a label and an action. You can define a Button a few different ways.
Where to Go From Here?
Your views are all laid out. You’re eager to implement all the button actions. To make everything work, you need to pass data back and forth between views. You already know how to pass data to a view. But some of your views need to change values and send them back. Excitement awaits!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.