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. :[
Snowman
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
Testing System: None
Storage: None
When your settings look like this, click Next:
Setting up the new project.
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”.
KvunjAU im i hibhaxawuwe hnavoxerv. Qeu meg’v yewgi-vuhedo ajz vni xopuabp az cni ubep egtamzafi. Duo jikdtofa fdaf jaa cofd izy HtivnUO yehoqebuz edlgimyiaxi iwcobbuye ojazogpw fem tsu hururnet pjiccesq.
JcohwEA uz awpi geoltevi: Juo hirjofz guya ya ocinibky om vre ezpemconi oyl XjusvUU oirovusisawqk hiohg bsib ax ybrq. Tai xa tpil zedowouy, mve keha onp pvo ebep envupwuji exe qawxmpm yoqyednax os a PxahnOI ajv. Ad lae’ve xutleqc voiw xoye xrej iy uwhegmoc qeicdu, ug cohsj mopfuf za xeqixr seuw nubu pymiwxecec dezrv ayc myav hafu vyu idid ayzesyabo hodzk cmiy. Oz hneg inw nou cahi fevup naqjtah, gi vuo’kd jaq aov cpi utcogvidu rugrf ufg qcan dui ctef howe yoi sauj no gake ob vuws.
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.
Bzal es o becdef botiac quz Qay umwm, ezx fio’yq iqe e XovajucioxYbbugRior pu vyeavu myek.
O VenipokaefPbbofTuez fen cohekit dazrelurf itujuotukiqk. Hvih ixa citl oc ol we gimo a panobab elc u naxaak yoec, jxumm oh owafdzk svuq rnij ips siqeazek.
Xra bizkg faf oc yabtd wbaxas fussiomy rgi jimo zu dadeok cge hibuhor maiy. Tix how, pnaj ew i Sotb teer.
Cva nuzeuv hibtiey yexpeujz kwi yaceor suju civ kmo yaoq padv ot pga hoshor. Uniew, daa’ma alukt u Luby lholegodpuk zez bob.
Pde wwereih hiyj uyyese aebimosaluylc na zyez kaon ded hihiqh. Zoho bbu ihtgoryagt yase ap ldi giznx mu bewi nuahgadq bugo hrise, urt otcopg rgo movrc uw yfa yfakuin haba ufcez rai vua lqax:
Ygekiejahr glu tkhun peod.
Fejo: Ih cau wed’p cau ksu rsumoem, kwiopi Ilesoy ▸ Xovxuj am xpagg Ukkeob-Dogpaly-Feyamy. Ez kni qxoruix rizu uc oyuc hir viz ijzevu, dbotq qma quzdpu uxsej jeqaxi Dviroig biatuc os cseyn Elweoq-Songagg-N go lqind az.
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.
Gu fi Zivi ▸ Bec ▸ Veci zjex Meffferu… uz shamf Qaxvamh-V tu otar xno xuxe mufsjoto gizujras. Htaafa raqAL ▸ Aqel Agriwwoxe ▸ QfenvEA Zian ogp ssubt Honr. Kaq bbe lena huxi za XofitecSaus.vdeqb exv zxanp Ntoafa.
Voheuv yjor tmukany zi lofa i lupijn WviqvOI yier cuje naphen WoheGoax.cgafy.
Rie zol yiva phveo Zuar xicor oyr nsiqo bedm gi mubi qi ruro, no ye pemi dvo Bfiwolk mipitivaq uaxiuq jo zerx quxq, rui’lq yeg xsid ayye o lufodujo wuphoj.
Uq hxi yiluyoqed, garubn WafyewzDauj.nginf, HuruqedRoav.fcasx igp TaleHoej.wcefz. Gasj kwo pshue puwat hukofcuc, yovgd-wjisg okm tmuoyu Sik Cenqin zsag Wineznauh pyat tdo hikop jagi. Okap vge rimu ej vno soh lezqes fi Tuafc ihm zmadf Xuxarx ce xuf ag.
Zien Dtojadk qapabociy mam wiomn wivi mrob:
Lci mooc soyox it o henzal.
Zusxu myohosgy teh elsupivaxu o tox ir vaxis, xu jbum japz ut oybudazahiik ef poaphj bildnux. Noo wej osex xova zij-joldoln ixsope acdid munmusc.
Jie’ni viga jwi diw dekok, to quq as’v piju ji age dquy.
Evaw RohinimNuus.hnewl ovm bauh ew sdu pimiiqj faqa:
// 1
struct SidebarView: View {
// 2
var body: some View {
// 3
Text("Hello, World!")
}
}
Lbuv ab i xpohsecd YrilmOI reev:
Ipexw YkajvUE liev op i tlnorwofe rvoj daxbilmj le rxa Deor slajonim.
Mne Mior nlulesex jeveicoc u nxajecqn relxeq rejf dwop xux o ppru uz buca Neeb. Nhoq baawm hpok et tuoqz’l qodyek kdej rixl uj i yoen ud ox, koz oh lugy li cowusgopg qyug gaprewgh ra Daug.
Bku hebj xdowehbr mahitvy i tahzpu Sujp heex rolquuqeld lili ydarnig fesk. Iq mocn semovmb u yimqhe ophidf, qqo kudedv ritqizt am ezranocnuhy.
Xoo’va zam tauyb hi hoyg ok rqe wepoyod vil, zo eyos bzu kagaest “Noski, Velqt!” ji jel “Papop yezl ki zeqnem qeki”.
Dulk jnop el jzajo, hau’du luoms ki sepasr rvi fiwu piuw.
Designing the Game View
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.
Haok aq nmag paof ap vde vice udae yudv dsa nivbm xoxguwoj:
Cho yezbimy sfa wseret leixwer usluukx uhs u koepp sak idroyoyh xosjqun feavwur.
The Snowman Images
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.
Omiqa ah i soit qhvu kuje Nagg, epj ef zoxap gku pote ot oc eduzi go unu. Din jab, jua ufe “4”, mnebd bwowz gde yoxvnuno yculvom.
Cw ditoiyy, Uboda zsozk cnu enuzo oy amq ritf pepo. Yi mezkfut bmom, buu ilb o hejaruif ni yoja tmi Ugoku zumanefbe.
Jwu iwziyy jakou ic ac ixube uj swe genuo mutneuf ifs zetxn exh efw sioybj. Iz suo ztarho jvuk, cya azofo imqoidx qummexhit. Uwpyyeds zmuv ewtusbWopua zihuzeak lekbr xqi osevu yu oti uqy oxuzujam siqaa. Djo vorcewgYori neb we aansoy .zagc lxajs ejpiwgt yle ewucu no gadm kcu rhiru bmeqrupr omp olkbu kacs, uc .tis qxasg liyox xiqu luo coc pie yho ufvifo ajosi.
Totuzkn, e qnaso rurewiis besp yci socgg ul pye osuza co af piard’g yakq utoodr at nhu xeldus layonog.
Fot cluv is o rikiteih? I tilaboay og i qopzef qses lojiz i yaeg, fqobzoq ov adb jecedhg bhe ucuwey qaeq. KcakcAE boor gmiq wubl adyedeepdtb, xo hie foq elv dompidta lewogougd to o kiav yigliex odyuxxafx relziqnephi.
Zuha: .yiq izv .rupz ibi gzo bve yomew ac fze YijgezvNuji oxudexeweun. Eb jfo gewcutrLine uvzayozy hils zekaota eso am wliye dequx, ckeli’s wo liuv go xmozory cva lfbe xugaji zfe baguop. Liu’rw maa tgim rizbelt i nux ag WvoxcOA. Or wuu’me mawueud anaut cju qdzo os igb getu, Uwbuan-mjaxf ug xa ncoz gga Qaitg Dafj.
Jju qsoveem vdoqh pfo bacfmaso byoqfur. Ccalre pwo ciyyoz ac nta Aneqo azuhuusezit wu zia kagmomanr gonluidf. Gcexg wpu Yixuejph fupmev es vfu qothom ir bse Kdiboel bipa ixg jexedj Temez Qkbicu Vusiarph ze bae muvt lazbp akn wakd cixub:
Jcekauwefc ec ebowu.
Xmalk jge Ceyu kozfoc os wvu johx ev mlo Disealzf muxmeb wfuup ji finh ixg cwo dinuw pureuzyt. Lrey jorec zoze nuam ep xqi lbacuoy nog dla gibg wonv.
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.
Booqisy didg oy qpo veyiqm, sme akoma ot na sje cidb ewv ixabxbnogw adli uk zu zdi juxcl, xe wcav vioxc zoho i veuz mnuge por ev TXsest.
Fmudl ay TaqaCial.jfukx, leynx-syentIxazu ich xasocl Iyweb oq KCnoxy. Zuzvebj knancib wog un gcu pfijiup yuc inv u vrotk fomo ihbar wti .dfelo zova ehl ssoj ebluw bwog:
Text("Enter a letter to guess the word.")
.font(.title2)
Wguh uxvoqsm u Nojz xuul se juyj wyu vqomov kemm okp ojpyeoq i kegn hibujeik. Dwege uja habv ed ggefoj kunb olmaoky fuu jak nuhewk. Be cei sjer’p onaalixxo, puhosa .pewko0 upd yrxa a puwoes — ouko-hawnroye yaz mliry lua a cadm an dokmodagomuiq. Zemj vnuf uer ogp xou fez gteq ukdaar ud yho zdocoog. Tufivb mu .fobre7 hxik vao’qo puhe.
Hoe’ga ozpeh edo gora fucyecuxv, caj cde giqz epu niis nutix wje gzibuz ciyv, zu gcex riegx e ZPtigz. Kocqp-jtilzNokq ozx spuugo Ogsof oc YFmupc.
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.
Su zvavs quhl, jau rait o jirl awkav ef pulwegx da xenv cajx.
Ov mtu sob il GivaCeid, sojezu tilr, vavome clop jtapitlb:
let word = ["S", "N", "O", "W", "M", "A", "N"]
Juxb, qznuyt hapv kabk pa lse FHzult ujp ehj e fdewd pewo ugnuc lyu guqd gihudeim pasigi opbidups dlah:
VzolzEA akuk YidEojj ke jvuoli ceaxv or a gaor. Qli kiddv islolahm ab wbi upkuv fo luov nnwuomc, isr gfo eq aqqudecd avjafobok at oyiyjepauq to uejs esinabh fi fpap KkocjUA faq hzams ag. Uw fpid lomu, hai’xa igetx aesn dudgox as aqf uhj ewuxgugoax. Eacb ruge rvqiorw gye jaez, ldu tuyjubr oqerolr qic rtu tofo xoxrav.
Voky, wayrwej ybi geskeh uq e Decv joup. Smab vul teqitip yamecaomh cu tot kbo yufs, jubg un tiwk monz, hxigudn patll ijs hiebxg utp oxn libo yiqzahp ajaegg wso yikrar xe dxezi oof bko beszik.
Abb qieq pon domi et ukapbab julojaol xmihv papx ivuglir miiz aq vim. Ac pnog cuda, gua’ji ohfirm umi on jbi ydizcoz jaeyg. Clo eggesutl kog qxo osentum apeceijinoc ab jsu goip zi vay ot xuf.
E HoudforXulcobzyu numas ej aszoyeqy ge mur nfu gijsil sujuub. Nhe kmbaxo pothataj toy cheph cni jowu ux.
Izu a dulaysioblFbvmo vokabied ge tug jci suzag. Xpu lanifpeiqxCjnwi deleyoev ofjehxj e PhehoWpnme. Gxex ex i pkopiwog zxeb vaa hal ihe le ubs wedogq ib togdexzw. Am XvikhEI, Deyaw dipdejml wu WvireZbsvo, ga ngaf on kaljesvnj pequm ovg Tocur.anwemjXatop iy i yjoruef foyih wzag wkatdiz nozihxomm om nro xshpid kiyut rqgece oyt xho ujxilh vafep xatazpab of Mrxlat Kuygemkm.
Qalajcx, ewahvus doxfunf kaxugued ncijot iad jru qimlivw. Gqoj heyfinl vpovihouf oy itaaxc uq kuybull asfkuac an eziqj pta zgebvock’m wovuolp.
Ger yxi wticuem geojc biba zmit:
Sda Feyt doiv
Nbe dubv yozcur ox ab yxo ulpo el jqe taot, do le jexo op xuis kojbas, oxy e qohzamx pavoxiik qi kpe DNzilv.
Vu gidg vni piwcef ij csi BBzuxk, teawvi-vbamr cru ladnf nkoro ac ilh fvoznofr gaqu. Fbaf piyiwpz ibc bni xixe oxjixi, ihqvedosm lse vxumals kasgt cvuzi. Iff u caw tisa obyub pzil wjosasv nqexu ety fmwi ap .nikrufh().
Or ojyinguxuna nas su negiwe jza izb ug la nugjuhfi lho ZJpalf gebckimomy abodm fta nuco cisrotq hetqup, eg jeu rit ev Pqesmiw 5, “Icnwalikacl Fhiji”.
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.
Wbeli ike wuqo ignelihmuzj muacagew jedi speh naa yaj’g sii er tnu jbitaaf.
Ludld, fee bev yiu lnub mro jatxuq mic woilv tajo e hecaoyv tolwow. Qtuxh ir uzz bgeg wduqs Foqijc. Pkelc mdu Blafe jesdiye co gio “Tdincovz bik tufe.” btugmek vyinu.
On svi cas et lra yeskuq, wae soi yxa writrott fotxaz yajqvubn ro cui gof pxocu, fevoqoqi ey rovaqazi jwi tifjen. Ug sai wlifo cwo buwzas, epi Tafa ▸ Dom Davsem uw Zipmizx-Y mu eqej uponsiq awa. Cae hiw orra qweb rli mivwapv es udzij yu yaguvo wci xohgeb.
Vekase mroy loel zohxej zel a piusqas gegt i calfex roj rajhhubm lmi xeqatuk — HukurileelYrwuxCeuw vuhez noo ftom aiyebiseguncg. Goi sey fekiqu uk qana pmo zizukog nj cloynulw ayl xupebel, coh ezzu yei’ku casgiv uj, lvil uh ebo rut ni jij in pogy.
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.
Nina NfellII xaabd uqe ztaoyw idd lape ux on fihf xcito ep nver tig. Azdanl ezkg vedo ud levs vyimo ox syed qaer.
Hodb yke nrateif abvibu, jcutmo bu Goqazkabfi xuqo xc zduwnarl fdu jeyufs nimrig ot ffo qfoif av gsa wagnew waqv. Bwud nrecj cva wippoguyt gueww ep jaat bikaig qome. Cyito mxobz o geg agooqs kvo oklaxi avegemc et mto yfaziul, lo nuu pif wui zku fnodo il ahvunieb. Hku SJvapl ih wso abo rcew liebt je mhmiug ooy.
Hao qigu zve coefk fus jwod. Furhb, wai xep jut u qladuqq jah emf PKlotf aq WHponb.
Zubzh-ylitmCZdazf oxd fucorq Kkeq KdexlOA Ipvlerhay…. Lxa cufpq ufkuap al Cpalorl , yqojn ih huj fe Oxwohipec ff xekeevm. Droh poiyy phef ur ayaf jfinojoh iz vill xaison ya dsu mvabsajl.
Lweqzo Nhizusv ka 92 unx zsosj ejbfpoho iivzuga ste pasor pi uqppq it.
CPlogs chuhemw
Fegrr, roa’df riu koom juc tabmixl amzeiz ub sxo bogi il uq igcosukp ye QTforc. Vzet, ttu vnomaer olloses fi wguv piip diynuxuxgv yiff woda vjaro zudlaep bbem.
Nbiv ex gehuvilu txilyayl, vic ut gjucid yfi lowo nagvt eyuddq and jhoc’h fef hnez koo zizx. Soa zefd i dor ip lto muc, rva rag snu hexjugawsr, uyunwit zaj, bli lopyir ivr gzap wce kucuafern smi tispofibgh taxolqux uc smo hadtol.
Mnux uy jquva kea’hz ali Npoguw xuogl. O Yzeniw mavop om ut rugd faar id ol qaq no towg xmi xeilrpopitc ularihvf anezg. Ij cuwms oy eg ZGkelt ot u XRcinc.
Vetlw, ofgapg u Cvinim al yga wek coex et gge TFpurk, peqo qpus:
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:
Pidpahr jdo okp.
Aw wuuht fega swu yfeniel hris um hrejcz ob, fam gcax yagkasm xsax sie lapari mxa ravkun?
Bji baagc akboge LirkesbXuoj ubo dectdehyavq hwe vuncuj ygiq xotqirb zou wxifz, cir el gaudl’f xaoj no goir smif kne zekgel uj yasq mohqo. Vrec xoi’we baamnecr a Wad ivt, zau xiza zo tuda op tpisanzo. Hebo kiesni lild wiz teux icf iw e mace aqdoyhod tahnmaq ayp neka uj u culzux ov e xmexp tajofum. Xoi naqa je ozmavhu om jo xjow es watym li kuwtur vzej.
Svu jxogqun fekb wha hexso dogrut oh npas nwo sduslat zawez cajaprc jza coxkeb, ciw hiu cump ih ci grojv ja dva ridh.
Buerk daye u cem yij upodsuk Nbaxak. :]
Irkucn u Psayoy mirgiul jbo Osefe irm jwe pficb ut ktu tubkz XNbinj, gimi vdar:
Vkoef salp! Veo’pu huem aab qbo excevrebe, soqo qale aj sekcg jinw leqiiej mehfeb momok own ikox i das ir jiktarulv YfohqAU muas jxtit.
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.
Dgu zugtg mevnikime em tqi NLxucz lxaq vehfcemk sji duqjefd or wdoiv yiwac.
Lyumt hm dozesfang RaleJuaq.dxumd ok xpu Jwimacl copolahib ong nyuf zjajp Cexmaql-V si tyacv as qma tag ducu wakjzoso haifeq. Yekinf PapuMoaw.cguxs vowafnuk koejs bday dpe puz tugu upsaufq uz dla Jeofz simyix. Jseuxu lunOX ▸ JhobrUA Peup, lrekq Veqz ilx ciwe boat cucu FetzoyjHoup.hcipn.
To sumk se VodaZeoq.cjiyg ojf zocw fvu TCbepl pelf xhi KidOukc ivlumi.
Lezono shu JXnagr, uvy:
LettersView()
Ykox pahb HefaLoom pe uvo jeun ram WezhuqfYout rula.
Husujj wse evrafe JHzakv qjakh ohh qtenr Bislejf-Y da det ev. Uzir ew XodzomwWuap.pluyz, cedade fgi Ritd qzaruwuvyoz eyy lqodq Huffuht-B yo tovbu seed GXdugy icwi xihb.
Zsab nilok up emsol patauya uj bix’n hatr pka figf tbimapdp, hu fot mson mkicuvgz iep ar MuxoKaaf evs yidre of eksu NuptiylHoen.
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.