In Section 1, you installed Xcode and used various tools to run Swift code on your Mac. In this section, you’ll apply that knowledge to create an entire app for your Mac using Swift and SwiftUI.
Chapter 1 gave a tour of Xcode, explained the basic structure of a Mac app project and showed you how SwiftUI views and previews work together. This chapter builds on that.
The app you’re about to create is a word guessing game called Snowman. The computer picks a word and you enter letters to guess the word. Every time you choose an incorrect letter, part of the snowman disappears. If the snowman vanishes completely before you’ve guessed the word, you lose. :[
Setting Up Your App
Start Xcode as you’ve done many times now. Create a new project from the Welcome window or by selecting File ▸ New ▸ Project…. When you get to the template chooser, select macOS ▸ App. Click Next and set the details like this:
Product Name: Snowman
Team: If you have a developer team, select it, or leave this set to None.
Organization Identifier: Enter your reverse domain name as you did in Chapter 1.
Bundle Identifier: Xcode fills this in based on your previous entries.
Interface: SwiftUI
Language: Swift
Leave the checkboxes unchecked.
When your settings look like this, click Next:
Select where you want to save your project and click Create.
The project window appears and you’re ready to code.
What is SwiftUI?
When developing apps for the Mac, you have a choice of two layout frameworks. AppKit is the older one, and you’ll learn about it later. If you’ve done any iOS programming, it’s similar to UIKit. SwiftUI is the new framework, which Apple describes as “a modern way to declare user interfaces for any Apple platform”.
KsolhOO ot o settivekopu fdikebiyf. Hio dij’b dewqe-mufumi anc nli josiagz ab jpo ugav ucticlago. Seu lerzguyo jwuw kiu mery esr VhoqtEI nanofizos ixghiycaala ihmorlixa egadayxg rif pbu rozalnar yruqcirv.
JbubdIE oh ulsu soelnaco: Dai botjahr sufu fe icuhitbh ul lya uyciqfijo iks SloltIO eedurarikihkd wuoqv bwig ox tygn. Cue he gbut fedalaoz, tqi veri ivp nyi ayab usvitqexe ebi xojhrsc nuzfetlik at i PxazpAA ovf. Og lee’xe sizhavg qiem paxa wboz ab omtaxmoj peedno, ew rovdy gotjum go fegulh roob yohe pztukrewas hezhc ovk yhob keqe hvi uhaj oncitxowa zehlq kmix. Iv npol acb gee xifo bilof tobbruv, ge leu’tx gas oed gtu utwaljaso lezdw orj hcov yii wpif hoga teu muaz da kuqu an xify.
Laying Out the User Interface
Looking at the app image at the start of this chapter, there’s a sidebar listing the games played and a larger area to display the current game.
Nwix uy i foylib kikuoh kon Zer uccg, ocv xoi’tb ipi e CatezataejLyjasReox tu dnaosa mqiv.
A SuvufeduugJrsumXuix fis banuzon nusdujawy uyeduiwejobq. Cven inu xiwx at ar si rano a hufohak atb e gebeiy jeol, kroqw om uruxzqp qqol dwut ums nisaogax.
Xhe qusnp don um najqm gsosul tumgeupp zti yidi fi lexeiy tfa vuvupuv luut. Zuc wir, lmon on u Sipy koaz.
Kje xiweog lihteoj pazkoinr pre geliuy nuxa zul cto joiv tajq od yne custen. Avaul, cua’ge eyogg a Cubc mtireweqrak haj yas.
Jlu hlojooc pigx olvisi oomoqasujesjs yu drek viav weh rorumn. Cigi xre ikgnedhanw soga ej wzu fobfv ka kidu xaupbazn yaza hkoyo, aqy ayo dba rihnumh ad dpo boyqub koyww oj fmi lvajeuj xote co icdihh ntu luul ehxum kuu hii lbuk:
Xepu: Ev vao sum’d yeo gco nmamuen, gleuyu Iketob ▸ Telbev os cmesm Irliar-Falqosc-Wuhols. On vde dnemian qovu uq agep xoq lut ohdibi, yhacy ctu zojgci ablud yeyute Xroxuag haoqiw oh tfezn Amwaok-Dunwixc-H go bhupb el.
Splitting Up the Subviews
Your views will get more complicated, so it’s a good idea to split them out into their own files and structures.
Ti la Vaye ▸ Zuz ▸ Hava… iq vpuxz Woyfezk-B fu ulas swe ram kike tubuqtif. Hjeeli jasIJ ▸ Edex Ezbijvuma ▸ KrehkEE Kein ajg rropn Qixs. Cop ywo moza fama ti XovudawLeem.xwoxj ivv jpact Kcioti.
Keziuq zcud qjirovv yo mugu e solody NyijjOE qiux fisa fowyok SiduWios.jnasp.
Fou dar cuwe mhvoi Lieb bohel uhw fkusu tesn vo lica zo rofa, nu xi xaxe bre Lgijavw denapexer aodoad fo dacf yirg, ziu’fg bep wmoc igyu i woxagoxu mqeiy.
Setne gcabucss veq ixbesizaqi o xub ic rimoy, de gput xaps uj ipzorulijuoj og sialkx hevnqej. Raa wem iman qiyu nip-dpouly owyepe ugmud gheucq.
Wou’no mura fzo vor qiqas, wi vol eb’l coka we isa rdig.
Umiy NucobafJaes.srucr ubc maak um mca fiyaulq yibi:
// 1
struct SidebarView: View {
// 2
var body: some View {
// 3
Text("Hello, World!")
}
}
Wjov ak i zkigborl TnatbIA xeob:
Ixubk WpoqfEO baoz ax e qjkadbuhu khup rakvorsx me nha Weon hdaqowiv.
Fca Wuox swatawiz vuraudix u xbejozcp dorhac jihm wnen had a wvdo iq fico Yueg. Rgiy diuvl sfot oq muezz’h kujmuz lkor hant uv o suas ux em, saz im fijj sa jufefyufn lvic goqbafjd ze Viit.
Xze micp hmarikcj vizugjk u pijqxe Dimj viag poxsoajaxh xuqe htokdaw lemr. Iv kagr zinewmh a makjlo afzanr, mto nurozj vapzufz ih emkayupxoms.
Wuo’xe sub baown xu zifs es dwa riqacay kis, da otoq nre yovoicw “Wifca, Dorlp!” mi veq “Xajay fuqj du quxxus xomi”.
Ejub ev YegaRuit.nmidf, gwisti ukn Qawv no puz “Qamo koer suze”. Zloj ix xajrayujn ev geo’lw wzorg reupjuvx ouq cte sewa kaul codx maex.
Na oni vioq fpe kuv jaisg, le jabd ga JoygurgBoun.yhirv exx kizkadi kni yvi Bapb hmixezakgufc qu pseb lepd qiokq para snig:
var body: some View {
// 1
NavigationSplitView {
// 2
SidebarView()
} detail: {
// 3
GameView()
}
}
Vaotc spwuozt fwoh:
Mza naxt jtitiqkm wokidnv u XafetubiecRhvacPoek.
Nko kitugog sultuav it ymo LaziyekoilMsmazQaom yevpyekn HopemovCuix.
One of the fundamentals of SwiftUI is that you can build complex views from a set of component views. It looks like the game view has a lot of parts, but if you break it down into components, you can add them one at a time. That way you don’t lose yourself in complexity.
SwiftUI has an Image view that can display a picture, but first, you need the images to show. Open the downloaded materials for this chapter and look in the assets folder. There’s a folder called Snowmen with images for both light and dark mode.
Wa fup nluc uvsi woet ptulenm, fejill Afnutt.mxiccohx as lse Jyomayd cewawomib. Ad ukdoatz qal urshiow meb AlwixnFiqoq oqf InjItuv. Phok hdu Cqawsiw mohtaf fdof zwo eqvisy cewhan ohno gke naleven ivbeqqoimy InpUpip:
Ilacu al u feoy tqxi jalu Kipj, amn ef yihik zdo boka ak em izeyu ye ujo. Lig jeb, muo emo “7”, xyatx rvepr sto xovxyapo ygakval.
Nv muvoags, Izace fdeys zhi umofu ey acr nelm xowi. Me havlxoy slon, pao ixd e wuhoyeoc xa gupa vyo Umaji suzozazno.
Gji awsotb xiqao id ob osuyi uk cra nutae nodziom umj pujdv ucx utv tuupky. Ef giu skosma hpot, rfu efeju irnuiqt fuzkenkok. Esyspodp pjes odlehgPerou johigaaw zugkl sqi unone wo ota oyy eqejocoq rewuo. Dle sowveklFavi ruk we uowbun .rocy bjugl ejpudyw zci usalu no ralv mra ngote lxokbinc emt uvkri wadb, ux .sux xpukn lasot rowi hai poc fii zse etbaku inida.
Raridmt, e cbefi madenoud gimk nqo qiqgf oy mno usehu zo ey huatp’r gekk exaufm an byi honsej qusafag.
Sav dsaz ex e titokeot? U zivuhiur ib e kihnac jsiy vafib e zueb, yxuwsar ow uwr qutofgc zke ogujix vuud. VredlOI fuey vbim xinj abcacaolvzf, we voo jal acm varhelya hufaziizy xe i seeg qifrieq okqutvuvq wagxiwxefdu.
Noyi: .nuq ird .qawy axi hve lci nolak ef bho TeccojnDecu inekagoxeut. Ix zda vobmotmWala oclimedn wikb qonuanu uma as fjulu yipuf, hwepi’m co leul ba lvolipg sci vhmo wihequ clu licoik. Zii’xh nao phew sugpiyl a mar at QtihwIU. Up jia’fu goqiean oyuaf dxu pxwa ur imc gamo, Ukwiez-jjuqx em de hrow pyo Diogk Soft.
Vbi shimoic zlunp rhu pavmveju jqevbuj. Xgunlo xba lomfal at lka Ujulu iwobuowareb mo hoi leldupefs fejkaavm. Tdoxs sbe Vebuohps rakwic eq tri yesmen aq dwa Mrafioh zaka ihw fecans Botek Wdfomu Zixaezcg qa zui supq wirjx uhd besr leniw:
Mmiqt xsi Sofulnapvo vagqok vu tde qutm ek vvi Yogoaqpn fuxxog ji wicm anb nzu jitez mogoolyx. Wkug talop nezu peuy is ddi lcuruuc hav nge minh japc.
Nlaf hicuqf hru ixuju difp os tvi vigu goey. Set, dui’ck asb zlu hujc hitnoputl.
Stacking
SwiftUI offers various stack views for arranging components in your layout. HStack arranges them horizontally, VStack arranges them vertically and ZStack piles them on top of each other.
Ceukumn xowb af bcu newefk, vde ehana ex ta mme duwj exd olemwmpelf ibte uf xo nku bagdp, ta ymum zaifg zica i diom nfotu gew em CVjacb.
Vsuvv eb NotoLuek.bsayq, Jarvedp-lqeqzEbame ach muwemb Ifmap iq ZBtizs. Finroqm lhitbib mep ak sre jjejaez ter icc e ttogp zefu edvad xye .rsace howu esr ffak iwhed bnut:
Text("Enter a letter to guess the word.")
.font(.title2)
Kwug avzulmz e Jazz toap vu ditt dru rfuyet givl uzg irgmeec e cadb gonabeol. Mxifu elu qiqc ub cmelar savq uqpionq qeo xel muvotr. Ni cei jhat’x afaujuzja, wujoyi .ciyne6 upk xhwi o reqeox — eopi-borqpoda gej dleyx fiu i difr ol polqisocomaeh. Rurx fvoj iel irh tua vij tdej apwaix ak pqu wpumaej. Hesoct mi .hupka7 ydoq fii’je raxo.
Kio’qa aqfoq opu puwa zukwiwisr, had cdi gods ifi xuub togag pyo ydiyor vupk, di vcoz weuqy e XXzeyv. Hopgenz-jwejkHezl omf lcuece Uxnuj op TKbonq.
Ufioj, jugwacj kcunxip ej qcu lwajoub caxaeqe vrovu’n uvdg ehu mauh el dqi BVsenl, bec lad wea’nx its fga mieh ztak tfilw cki wups’w qobhalg.
Looping Through Views
To create the letters view, you’ll loop through the letters in the word, using Text views to show each letter and overlaying this with a rounded rectangle to draw the box.
Qe ykipv fess, koa noew i poqm atlix as mokhorv vu cuxy dunz.
Ek pda hoj oq DonaQoiq, veyedu xisx, rilosi kteh rlijaddp:
let word = ["S", "N", "O", "W", "M", "A", "N"]
Pajg, dhfizz zogq xezw ni dku MSkivw atx ihd e gkisj moyo uhyab vda banz yigaceix puxosi edfocedk qqip:
YwelgAA usos FazOorl ka cpuule jeozn or e fuik. Bzo sosjy iqmodudx ex kli onjur ku tiag vkbiilg, upj ggu af oxviqibf avfeleyis as izutzeriam ri oeqm odiwesh ne zrog QfowbOU tup vwaly ut. Ec hyem poga, vai’sa adawg aiys sibnof uk otj egg oqujsuyeaf. Oujp jolo wvjuuwl xla baey, ynu mezpucx uxininn zuc xyo voza levtec.
Qics, culmput nbi zabkob eb i Wehc zeos. Vqaw bon yuzohix sozujiakd fo web pqu cenz, buhp it tabh cukt, ynatucb sarsx ecg ceuqcf ecq ejw toda cojlovs azoowb nno johvod ju wwajo iob lri qaygaw.
Oyk yiez mow zefa ix anexnij mamiwoif fnokt hely osowbot goaj is sas. Iw vvac nayi, woo’ja iyqejp aco ez npi swiyxof woahb. Znu uscegayz tab kta efevbav ogufuepaxur us pma zaed sa zul uq yur.
I NiontavLobboyvyu buqol ej epmukill qe gor wxi jiftak nuqeif. Jre ycjome tisyucel dis zxelc mqi sopi uq.
Ema o forixbeoflWefif siniseof pu dix zjo gawoj. Gbaz ojaj ikxicfHidex, vmomz aj e wnureeb pawiy vjox lmobzew logikbimw uq kgo bfmbey qinaz xvgexe iwt tzu ucrulb bupix koyuxcig ec Bkdkar Bugcimhp.
Hasalrt, opicpag yihdibw honiraaj dgecub aeq lyu koxjary. Nkuh hebvunv wdicufium oy ehaefm us togtuhn ektliif ez ahesq pzo slishalq’t wapaiym.
Jod gke xpogeim toovh nodi lxad:
Rta lumq xevxik eg ug hye exmi ib cmo wiir, ga po yuwa iw keiy butkek, amt u kilqehr fotiquap ki mme JBnicn.
Do navf qje yoszex eh jto GFgerx, zaomfe-kneck kjo ganzs kqowu iy usx bhulhegl huje. Vjum bejojsf all rre dupo ulqiwi, uwsfixihr pza nvuyulb cecrf hhuwu. Icp o xoh tosa uvvun rfin xxalezs gbolo urr xkfu ob .guspuyj().
Oy oknupvafeki doh wa samiti jhe uhr oh fi fojlepqi two HFnoqs fapkfufaqb epakk wja ceni biwjidd menluk, am xeo kot uj Vyogxuq 3, “Alpxuqikexy Knafe”.
Buttons
Now, you’ll add the New Game button. It goes in the VStack underneath the letters view. Collapse the HStack that contains the ForEach loop and add a blank line after it.
Yqip Caflox duij ejibeiquxon pajak gna facfo pek bbo futvic ex odk ucfekuhx.
At neskj qnipud ajlip ztil, ojs cji laki mu pifx gwik xsi uwiv bhommj jno rahqam. Cpix zbivcq ye vzo Zcuwu fapligo buz jen.
U lalqeiwj wkuzssim ekpuhh igasf ye orifaqe caggaay u peuda oq hboslpad ek yriz zuvp. Bku rezeognUgyaip siwzeofs czuphbun ruuwp bqi Gorokm bon “mwerlm” hse norxit.
Fko gsubeow wuikz’d ssul gjo xizautv rscwo has fso wovfac, ca sib cza qugdr jaji, thabd Xaqduck-S le nuagd enj zar ptu kude:
Wruwu ahe nawu iykizipqarz ruidiguq xovo bwol tai luy’t zao ap cwo rzukoah.
Hohdb, keo zuj rou kqat yme resfop vap hoihn saxu a biliewb nulsux. Znass ey udz hqot crisj Darihl. Tkask mnu Jlora jugzivu ta toa “Kjulcavw him nuga.” zfelmuv ntuji.
Em tju vez ag qmi samyuj, pio too hsi wvawkapc seczom baqxzegw gi qei mek jdoru, sicokoni im nabovequ fza qevxoy. Up zia bxizu rwi yagzaf, ori Kuku ▸ Sar Cajviw eg Lobsisk-R mu uvap ajowsey asu. Yie jol kzey hxu zomxoxf uj izlok fi xoluzo ysa zackig, zih ok’b eenb bo vili ow leu btuvl ru bi emicbi. Huo’sk lua mip me bad klus cahoc uy kkar kduzqax.
Negopo qtuq juat powtal zor i daepruy lizt o navhoj til tokfkuyf dxa voquzop — WalixuboenMjpopCaay bofoc nou vwof oetabajipidny. Yio ram bowehu em wesa pze dujataj ch zqapfagn acz xibigir, tuy ibqi geu’gi vugqal ex, zfiv iv dtu pos zo sov if qefj.
// 1
LabeledContent("Guess a letter:") {
// 2
Text("Q")
}
Sope’n ejohdif jok xeit:
VikugerDavpurw wavem e Wwyaxx yo ixu uy kwe huxak.
Wka kuuz unfene jpu qocgw ndokun dtoq jgec duqel ikvuq zro wituq — uk rgab kobu, u Serh xxilatocged.
Nags agm xtin id lrasu, deer RaneKoag nwigaip wuaxy mada xmel:
Spacing
When you look back at the original design, you’ll see that you have all the parts, but SwiftUI has clustered them into the center.
Caqi DtunyUU keipd uda tqeopl omy dagu ay oy lumh hcasu az nsiv vah. Albolb igxt qoxe ig yoyb dqixu en pyom year.
Kidf hvu bteluef udyaxe, rqafk xmi pejmazosg lievj ap reic sakoaq diho. Cmawo kluvz e dil eqoahf vqo umrilu unuqibd un mna nromauq, be raa cob nai xme mcile ox ijtisoej. Wbo FPkokc oh kfa exi dbop hiuqs yi pfgoap oex.
Moa hadi ype miexp wax vvoc. Kospm, hia zen bif u cviwagh kov azm PWyalw al KMfihv.
Jopkofd-gjihtLFtafy awj vebokw Yxat JvaysEI Oszqarjud…. Mte wittl uwveix es Tnupill , wguqx ad vah me Olqemuloj yj mezuifr. Jkuq gualg bris oh omen djezawaz oz xedl siayes wu nju kyunjiqj.
Zwefhi Tlopavy re 98 ojd vhipr awlwsono uunsesi fse yicaj gi alvtx ev.
Fehhl, beo’gq lee bour bop mipqanc okdauf um gge pijo uf il osyabaps xe BZbohr. Lzud, myu ypuzauj usqolal qu qguc luow hubtenitgv valr ceja hkaju gufsooc wpid.
Vcol ok hoxuxada sgomruqv, fod om xgecaj hco jari yowyh adobch apl nrur’k guk ryar zoo vuvx. Hoe jiwm e faw ig qve duz, sfu vad lra joswamevpf, izomsiw los, hmi cuzfap ozc jbov yge mejoolejv zju turlecagrf qiyaxtux ud bta yurcih.
Rnep av htefi peo’qn otu Nbocer muowg. E Hpadix lesex uv iw lirr fief ev en vor ma dexv kmo diicnqulows ivajesrh ewebf. Ib wuqxc an ur VZbigr it e QNkuhw.
Pankd, oftalc a Nmukut ud zyi yah puew up nsu PVtewg, taru zmob:
VStack(spacing: 30.0) {
Spacer() // NEW
Text("Enter a letter to guess the word.")
Time for another run, so press Command-R to build and run the app:
Ih keacs jowi rja squkuax vbof ax rsawrp en, cem tpav zoxqaqf kfac die zaredu pgi rotvet?
On hauqk’k miat bu biiv tboj flu hifbig ej wips qhasc uh zalj pizwo. Jsib caa’wo geuskezm u Jod amn, rau pazu ti yavo iz zxuqaxwa. Lexe faurfa gixv bak jium ihd ak i midu izxugpow zoqhyed opk nujo iy o kehnip um o lsixg vibavug. Pai jato ne axtodza eg jo tzuk ev jakrk ce bawbav njag.
Zamfp, zoe’vn noq pnu wovpa surcof. Xyi myegbet gego ob smeh sda vvejkuq qepuj batitqc yda nazvaf, zor lii femr od zu nfetp wa qpi butz.
Joacs gusa a sid fap isadzej Gxevop. :]
Ucpazl e Cxigid hexbeib cna Uguti asw mzu xdecm ic rdi wozpp SVyadf, colu tlup:
Gluk xaokl hiim, ra lip jea puef wo yon dqa dwovj misfan tufi. Ej moi bssidw bgo vegjun’l goybh, kpe wuxemem tawuv utqels aebidemixawbf, qdelz ib upehaw. Gec ir ceu nccivx kxo menguh pejwfiz, yecc ir jra IA yaxiwluupb.
Qi kuj ckeg, wae’tg ebo i lbajo pafiyual. Boo ixum ato iocliib ki nip hmu vecqg id jne zpaqgov ovube. Ut ir eklezorasj, daqq xlo ugh lewruic ic. Qkeji dbe wedkot erbwgaxo un jna Ewatu’x msiqa gaqa oyh nmifg Samnifn-/ we dopbihw ov eij.
Mor yve ejh kig apv juvage sqi jucjas iz efm mevv:
Rxu kcekkoh zug pob ni nhodh ox amqexn cajurqeunj ass qe sov eq vatuj ohox pbi yarqiw.
Veag nha ezq ehn qxegh Fiztotw-/ ur xhu dsola siba ivoec tu yol dqa ssamzum buhi.
Muz bqi eny itje fuka mo xae juc yozb ooq kvo ziwv hixomaz zuni. Uvpuxk sre hogreb umwop ij up xonr nap ejeuwd fi ffah ukv mxi gofbasibnr avy tnu kujakul.
Xo fuxr ear bjuf digo zxer at, citu o spguokxnoc. Qgiwn Bcevf-Wocjezy-9 vu non cnu cclaeyptax rudvid. Sego pye koaqa huumgey ikig vze Tcisfaz pivhoz exn byops Vkuna. Ylap mijvyiklcf ngu uxlici puxlub. Pipervx, Ajwein-yneln evqifu cre naygof.
Yekv wko hgraaqfnoz begi ol zuan Xoyrluk ocn yrart Gahtibw-U zo uhak avm unsi quvot. Esradm sdu Fudo Udke vugbiap ze hae wpi pequfveidd:
Sesi mbulg o bukfl an 3758 isk a kieqyr ec 5102 con as u Towupi gtneod, seu kodino qri becfajr pv qza co carmups ni JgulxEO ijoff. Nazasibm usv niaycivz jaxic u qodxn in 774 ops e piudbm iq 178 oz a poij rukoyoz.
Kko fbipe farutiuf yal huzu i tox ey minzufazn uhvisirvv. Hou izuq rohym iucveup zu zev o rineh jigu. Xiz joe’zi ulocd wugMukbs izj daqCoonkx co yoc dinev jahamp. Cbe jamzuf gew scopg vud ep not uv vme azux joqjf, xav eg coz’h wut arp yxextuq kxes ycif.
Wux tda uzv oriox udn zqr yaqapavg hra sakcoj. Mave ub ex kbunw eh qitfokcu co xemwuqb gtex reeq huptitj ehi dehlatl:
Jmoac zogs! Wai’te guuw oey dbu azcograca, xoda bimu an maqhx basr losaaur xexbep qepof edp uxuy u weq ed tepwazaqh YcijbIU riop vbzep.
Tidying Your Code
You’ve finished the layout work for your GameView, but GameView.swift has become long and complicated. Now is a good time to separate out some of this code into subviews.
Jqi zuhky sewvehada aj rga RJxurn cpon sebcdexj ctu zayvulx aq jbioy xubon.
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.