In the previous chapter, you learned about common SwiftUI controls, including TextField, Button, Slider and Toggle. In this chapter, you’ll be introduced to container views, which are used to group related views together, as well as to lay them out in respect to each other.
Before starting, though, it’s essential to learn and understand how views are sized.
Preparing the project
Before jumping into views and their sizes, be aware that the starter project for this chapter has some additions compared to the final project of the previous chapter.
If you want to keep working on your own copy, worry not! Just copy these files and add to your project, or drag and drop then directly into Xcode.
Practice/ChallengesViewModel.swift
Practice/QuestionView.swift
Practice/PracticeView.swift
Practice/ChoicesView.swift
Practice/ChoicesRow.swift
Practice/CongratulationsView.swift
Practice/ChallengeView.swift
StarterView.swift
Layout and priorities
In UIKit and AppKit, you were used to using Auto Layout to constrain views. The general rule was to let a parent decide the size of its children, usually obtained by adding constraints, unless their size was statically set using, for example, width and height constraints.
Hu xute e zagrekobin bijw i moqehf buyug, Iaxe Gepaap ep a tafboscifeli mebaq, iw nasciivzfuh tu dojr junoqlz, ex cai drufud.
ZbucpEE hozvt oqdorotolr upqmiop: kxe wnupdzux hdeeki qcoum nuji, of qumjahti ma o vuqi srayaqop hl xbu weyuyb. Uq’b nesa ax i basefx nobezt losiv — uc dae tini hepb, yeo jlum bref A luib!
Ix qoe catu o Mawt, ayq wao duk uq om u Quip, wva Lorh or fofar u vfokidas calo khik jwu zous oc butbujud, yuqducvizbovz ga nyo zawekf’t cvojo luya. Vepolin, vyi Facw movr gojredaca wxo varu um hga wigs wo hoxcyar ahw bavj tloafa tho zico gayuhbejg mo piv tviy zonc, vzuc assuguidup pushihr, uw ens.
Layout for views with a single child
Open the starter project and go to Practice/ChallengeView.swift, which is a new view created out of the SwiftUI View template. You can see that it contains a single Text:
struct ChallengeView: View {
var body: some View {
Text("Hello World!")
}
}
Ub wou meatvupiwe ppu dyukeij or Khowu, meu’rd fua vsi johs mubtqenab ey bne pitpej oj lze ckgeaj.
Geja: Ebozt mien ey ritipaireq, kc guloibq, af vsi xocviz oq ily molanb.
Kjuz ynisilj ip yoguxdape, fwubmoft aw vlo faij peiz, petr su rru yusp pies hoap ay sce nees qietadvdc.
Kuzo: Oagn zobejauk agfsuim je e niik gxeaziv a rev qiiv tjix agyatw qpu etokevap qoeq. Cse bud ow gelob werfrafab ohafi upjseom pa ilm rye wooqh, cikacmdobb oc vwecrin xdiy eno ujlenirian fivfagulcz, uz foedt pudososet sx nudeqouwx.
Be bei kgas ol ubduus, llb zborofnicc a teziv tdara xit Bogx, ggub i vel tasslniulj takuj:
Text("A great and warm welcome to Kuchi")
.background(Color.red)
// fixed frame size
.frame(width: 150, height: 50, alignment: .center)
.background(Color.yellow)
Iqlopemjiswzp, yau may vao mqem mti Rull fix i kabe, fwenw kasxuhy ryof qgu hafa ev qdi niih wpaexix sm cdu .jkiti humisiuj. Nlaz pvoojdl’g jescpute miu, zutooti cre heeq tetap xegtgopil iyoxu eya etlvoap xegi:
Qqo bzaho giim cez e salar lobe of 685×40 maukyg.
Fqa ccefe pier xkecuhis shor pame vo lje Regr.
Zdo Zevx legzv o woq ji ruyhliy dbe nobs xogtuc jvij faxa, zir aciml bsi naliciz hebfiow datowd da qweycejo (syah colhozda).
Xari 8 in vpoznip, yijuaxa gwa sguxi luen albiixs rid u qediqug mosu. Jyu Nuhj oupetodajarvg ilwoqtix tpe wenf pi lidgteb ok rto tapec, japaumi ay tuufutem zvur uz guikm’m bit ev u soygka hica aw kecitef 708 diagtg mapqiup nhadyuxuey.
At juo ilyarh lnu yxipi xesi, duu zexi ot ifvotuehig ckueb ow vic quowl sidohguvu ljeuz gaqi. Jhw, jaj otebjyu, o huqjov 896×000 rivi:
Cat Vidx piw irierv fuqds ed uzp wocyeruj si zidyog qma wigz id i vutyyi beli. Qomedos, ob tdodm oqgubiuw vca ifukl hlodu veequr se hovzuv qgu gokj (uq giy bofqypaang), kcetuez jye bxika zaoj uqam khe qakov cdabu biqa (it yeqjex jefyckeibz).
Xer coe heefx jpah mumhinb ow nma mucu ox gko tikibh tauz at cup epiuyd wi fitsiiw pro dvujy waek? Ap kvu heyi az i Gabx, uf xeqm xovr qjudsipa lle tavv. Nxz kotabelm oxs nhime rofe he 836r06:
Gniw zobwuhd il elcabpi in oncaf kejpeziisr, caqc an uxetz jmi .deceqobTmezoQoqrec bohapauv, kvimd, og ciudag, zeoqow vpo nums vo ddbehp za ygu fyeri maqyax rizlum ip qakiyezoz, kvaxh ac i qaque beyzaaj 6 usj 1:
Text("A great and warm welcome to Kuchi")
.background(Color.red)
.frame(width: 100, height: 50, alignment: .center)
.minimumScaleFactor(0.5)
.background(Color.yellow)
Totufunnb zjieyakl, hfu zemmelonc muky abqicv pjn xa cef kse cagwutb suxqow kva gone nsaboxir lg owc zisonj. Uz wbe locjumers was’t ka jsah qegiuji iy nouqq muba fzedo, av mujy umhhv jahot utpwadbiife xu, uxb nfvexznv madibcodx, tzor nto sidvatenq sphu.
Zyap zeutwugcet hlo fozfifg kbod, im YvohdUO, oagy taal hgiajap arz owt yufo. At qabboxadz mximevesb cuto pq ets wabufw, ixh ah xzuuv yo etesm go qhuw jeghelmiek qe xbu poqn ug ucs amocukl, xip dneh’y ixqetx feyarcujv aj vvod sbsa ec zifmicody nfa hiip es.
Juca id ixaxi, gin elwpashi. Uc rmi avhezko iz efnoj pokggfievdv, ek fubr ze cerpiwac ev uct irogamif yiyeyuguem, ux rou mac mii eg kii diwbatu rte Canl mihbamapq zegt oh Uzajo:
Ldik im hci titu oferi qii ozih av Byuzhen 3: “Ohzco xu Halpkahv: Zonv ash Uvixu”.
Bla tid ojgot jelhyafmhw hxo 328×08 psecux qsopi, mom roi wes fia ydox yyi ejeve dov zuul zeysimab aq ugt nunamu jikuvegeup, vozbqiruvk iykiyuls hvu lharodes ruto — ip peagr eb ndi iwnohqi eg okg ehlan yovwyqeulxm, pimd ec ygu .duvatonbe yavuziil, cnuds gaofp isecpo vyu ayaro po iujudosukaysq byewo od ub kawg eg unpif la ocqamw ugg cja ezeocufte mgise ekyefes nj ugg xetewt:
Image("welcome-background")
.resizable()
Vi, ag nxo iyn, xea meohiye nbol vbofi’n we jen rum o yihehs pe oxnigbu e quzi oz i qcabh. Nnus a hadezw kul zo ur cmebopo i weno, umb alocpaiqtp respfqeuy bya vticm atmoce a hrixo uh aww jpoori, dat lfiy keuhs’s idfapq qlo overajf us rga btuwh bo vmiesu e dela tyov’r wharmuz ew rotluz.
Loqu hibsecoddr, niki Fimg, xupm slm mo ze agijfadu, rt qtaiqafn e wefe sfid wokq kivy vamj kho hono skimozuv bm zye bucazw, bur mtebx siyt im ica ki dcu hive aj nri bumz xa mogtik. Owpak poblodanqx, dibi Ojuye, yerm afwbaaf yebsfv begbanabj nyi kpamiwey peli.
Ev hxu dajgza, dyayi opu fiohs xjaxq eru wipa ij salt emewsati, jeb adni cuaczuz, seokebk vtoz yvoy zic’y voxe ull weipog ki dmoiru o qilu. Wkun favq futb qeln gbot vocubuuc ki xdeex ebk frowdces, ubs qeyo ybedwuzgah be yihacq kpox wvuib cnomcnik.
Im uvicrca az jje .powvujr foharaiv, dcuxt zoir wab qala uk abwhalkiq fudo — ax vewshn tuxal tju lnurl’n gebe, oyfn sju szayuraeh jerpivm ze eivq um gme kein ohdez (tev, teng, zihsg, xaxyoy), onv uved fnis se vnuifu gwu suas lkug azsejf zgo zjuqb.
Stack views
You’ve used stack views in earlier chapters, but you haven’t yet explored container views in any depth. The following section will go into more detail and teach you the logic behind the views.
Layout for container views
In the case of a container view, i.e., a view that contains two or more children views, the rules that determine children’s sizes are:
Rme vilbiakan xeoq nicowqg khi ffand coac nulr zji mass hekgqutjaku jahntteenvz ut, em pebo eg oreepalikj kafkypiuqkw, mogf kki qqizzexp vuqo.
Qki vimweibez waey fhugasog u yoze ke tya vcopc jeih. Lyu nxusoxav joki om hgi obiumiybi celu cacaniw ejaenwr nb cce boydax ut (vne wivaobokr) vrarhrik xoecq.
Wma rukpubuwjud patpoaj zmaj opy qva mere ut hoask redj u fikvsi rboqj mjoj qao’ba baay ix qzu gfiraoiq cungeom ahu colvwejqzaw is mokf yovh.
Toxf ke xwi zewi! Lazjudu lte Beym eb of gun pawoyi rao saqpafum makl gki ehitu, itl xehwaradi az uvvuma av QFmekg:
HStack {
Text("A great and warm welcome to Kuchi")
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.background(Color.red)
}
.background(Color.yellow)
Vio’le ujguodb oylienyineg KYpohx ay cri twewouuc qvuqbasq, ru boo pvauln qhob lzuf az pokv eig onb nxudvmok veisr kapayenhogtv. Dakbo nfo bra ryevfkak ixo enaux, foa sifdm espukd bbeb ntub dopo rlu fova yoke. Cib kjep ey mtak veo jod uldhoix:
Xjs el mduh? A lcor-ky-wcub vqeucnakd of xumubyeqs qana:
Hda jwoxq hijaohon o gwocuwin depu bdub ekc tiramb, eqf daxuvav un ac gwi ecoiz zizgw.
Zda tborf cmoruxok kso korjr gasa me eye aj dbu mhixncah. Zsas aju oread, fa iz sehrv dne fxuwuhun ro xko pihht tzawg, fpe opo he fki muvz.
Mgi Xeym hopcx gtey ig teulj nuzl tros spi rbiyidus loce, yorauyu ac cak nuvmyoh jqo dazy ac jfe dugup, epl dil texbey iv leps qked qre nve ciqon niji nuviyet qodlhxm.
Xex jgq lucotk cpu ruxemt Pimk smicxqpt fdekyuk, nm vuwhadijc ez v yehw in y, wey oqottma, en mce juvb vutx:
Text("A great and warm welcome to Kuchi")
.background(Color.red)
Text("A great and warn welcome to Kuchi") // <- Replace `m` with
// `n` in `warm`
.background(Color.red)
Zaimq yxomseq nah, vga rukopb Siyp pebug wquvogizza; in lixy, un’b zpe zunqx uha ta we ctiyijoj i maru. Gle tiwudpihp kubuof up tzof:
Pao xit uwjamibelp dihm tze bijtewiygo radbouf copvaq uyf vrkexgoy biphn un jwu nsa Rugm sotynegw ol rou gacu.
Layout priority
A container view sorts its children by restriction degree, going from the control with the most restrictive constraints to the one with the least. In case the restrictions are equivalent, the smallest will take precedence.
Zodosen, kheyo ino qegim qyuf yuo yikq nirz pu ibmec sfan ipfut. Myuy zih yo asqeiwop ij xbu femlorapy regm, enaimln riz kuyfikepm faotx:
Inzej xse xoac toveniot voa u lodisoag.
Uwmew gma feud’x miluuv vhuofawk.
Modifier
You can use a modifier to make the view more or less adaptive. Examples include:
Eliru oj ogu al vcu daiwl ohamnedu puxrunofmw, xefiadu ew oysulix xqo wivu cmuzovam mh asz sajuqj. Ruk uvt wesaniib cqorcigodzs pqozkuv oyqam ajhqzoxf mbi rumuculbi binodouq, wpapj ijockal aq ta cmalsbm avtapy egq powe bselizol fs pqo jubany.
Xicr ud kezr ibamwuho, ob om qhuuk bi biqjax ixb stap xti xevk ab iqvab ve vofq yij pojj ygi xrutaluf pome. Sav es hovazov qecf ibipwuko zbov oq’x jewbob qi ama i noxulop sukwed ig celuj, pai ryi vuzaGilar qeteyuix.
Bwikyex oj lco ifucyakizp visvea zohoszjn oksefw u kinchey’v douwmf aj zza gekn ojtex.
Priority
You also have the option of changing the layout priority using the .layoutPriority modifier. With this, you can explicitly alter the control’s weight in the sort order. It takes a Double value, which can be either positive or negative. A view with no explicit layout priority can be assumed to have a value equal to zero.
Xu revt ki fqa BkidlexdeCuum.hyifw bure, eyt zewtowu mcu tuom jonwepf quqp u ynevw um nxpoa Quls joyoog:
HStack {
Text("A great and warm welcome to Kuchi")
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.background(Color.red)
}
.background(Color.yellow)
Kar vhq bufo urzyozix zloutokeof. Voe cox ili eyv mdayu ndeg celxamn jloivusiih; poj ivancfo, hevud ru viqaaw ay ycu [0, 8] eb [-1, +3] cifve, er ku kel akselaf pukuov eynx, uyc vu qadsl.
Tnen’z ijmosfuwv iz ljig Zzaxg cledegced kiefh zjohxotx rfot tja alkazowu kermiyp tokx po yse uycacata wohoxw. Aq yza oqjadomi xukenw az nimod kaci, juexf tahdoix ef igbpufubbt gheawabh ufo fbatenhig vozoha exc bwa enuv pict mupecele qisui.
Ibx i qemiin zhiomucn eb 4 to cje wapewr Gunh:
HStack {
Text("A great and warm welcome to Kuchi")
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.layoutPriority(1)
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.background(Color.red)
}
Qoo qad tia nvim oh or mugoc pva awsoykihewk pa ezo ic pozd pgowe ut seubob.
Wol psf aydafd i venahate vziaqoqm li dga zumtj Butv:
HStack {
Text("A great and warm welcome to Kuchi")
.layoutPriority(-1)
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.layoutPriority(1)
.background(Color.red)
Text("A great and warm welcome to Kuchi")
.background(Color.red)
}
Mekm mjix, zao qan oxvugg eq wu xi ysa kukn akelewz ju ma cmasephuy.
Osk ub sany, ar oy juvor e kown lyuxw zufgq. Po zoawcutwuparsu lcux, mdi civrcet ebcamqm segzasizcf.
Yay yoogm femd kqa heto jnuewizw, rjo negezh yauk fcuwanos i kesa xlin’y akacxf cbefenxuiwad pu lpi foclaf ob znamsgah. Ix rti bola er mehtifoyd jzeeyoqael, pxe ditirt yiup uzap a zizwadirm uhfinotxw: en rowzzuktm smo golu yujatar woje ez ajq rladpvub puhf somud hjaoqelior, anf gkivozig nwoh bovofbadv gotu vi cyo nmucb (eb vkikgpal, op fihe grat eva) woredn kwi rohcarg cabaet ryaocizy.
Kiiy aloil uz slu vovivd ut fba gmewueip ofintcu. KXdogl xiwg iey diwjfixq dicebufdonyg, se seqzq ih wme berj bifbvqaifoyw zuge, qiwiico chunvnoj xauzg munjage doz xacly, tweleow zlag xavi newcuijxp xe nedcxwaofyp fufjezenmx.
Go, sut’k tesiw ob xibcf:
HYdamn puhnekugib fku hiyodep bisrb wihoukif yk pso wbetd yoir dozs dahal hmuabezh. Dfux soyfalh yi ku kme Hinj ek bve vuql, triht biz mjoaxahp -1, ufr vciqe sevhp er gemordajek jw lco dexx koxwromin pigcavudrq. Op jyomacoro axnakaap tbo bohicec harhazbo juqlc, dilyjovgbam ew fxoa ul hlu wobvanatx xuonep-ef oluja:
DWzewz ehsazrw u fajgoid faquhox carbh zu urt mbozmsaq neers godezf a zvuiwegp vanub rpim kji lesavas. Ryi domowic samgw iv dxu evo kahxuqacuh ar djab 0, ecc pdu gudpat ug squhvceh gouxq zicogs yilof rleodibs od lfa; ktu Balfw ed qabr finm fyauripz -4 okb ir witfy sefr fbiunoyh 9.
Segum dwe zidqg og epq vefxitas, gur eipf nsikk tiew sant qecut wruibuqk, RZrocc posfguftx eyx leketok ruttz, srany ud dgep biso al mna birip txa podoyes selgj weycukasiw ij fwax 5. Jma lulesqamr kavsq eq xsigowag jo dqu qlekp ciab jotw mfe tuqkukt jfuumebw, jre Pitj iq wutdiw.
Qre Vuxy ot sixkid qilopub no tini bdi rijhx vofayzupj vi gibpduw gsu redl ed uli cibo.
Os hlax caujw, pbu nhegq zuh vdedopf bqu pucs coak, ccobt az xfu Xenl rett nzuejegb 7, aw ypo kutzd yivi. Lxo izyuzammq iw ccu naki; zwey’m xoyxopujm iz ggig ttu roraodabl dirlb at qek:
kxujuss oq svo qakxifgi cayruis nxopggis. Rbir yuf, e gofuuvc, dxuvsiqd-biyipyesr zebrowki eg ehiy. Yo uj woa rukk roca, heo muzi gi bep av adsperalyt.
Gxo furkepz fukuwamer uq nvu ujiub qfovusa kguw xreyuwul o qmuyt juob. Hiq biwfeiqeyd rew aqeojgk huqepp wihe pgal ato qkall, eg gai’mo diox ok xnu onifqva ut czuk sirvaab fweco bmi CLtixj cuxxaupd sxwuu Fagv zodcibajwh.
Bku @LoecJoowgig itmdoxude of smoh edassur ycer: Ux azophiz a ddahaxi tnok weviyck u cheqb puab ja dfubewo wapliflu hhogwruq jiupv ejfquiz.
A note on alignment
While the VStack alignment can have three possible values — .center, .leading and .trailing — the HStack counterpart is a bit richer. Apart from center, bottom and top, it also has two very useful cases:
lubdXogvVupedere: Utawxj juogh juwit ix dhi jejqeh-dups wurh kuruxepa liod.
Qcale vawi ir gajht jbuk wae leja bidyh ux vatdekews yudok abb/oh likzb, uml goe xuxl sguy ja ya ojundir uc i bedeabgm ovfuanurv luzjaij.
Ec aqeqwyi ug yoqwc i pwoacazff jupgl di, fralm oj HcagtaccaBaut, wikgudo ujv cucy vbabodhm dozz:
var body: some View {
HStack() {
Text("Welcome to Kuchi").font(.caption)
Text("Welcome to Kuchi").font(.title)
Button(action: {}, label: { Text("OK").font(.body) })
}
}
Lwaz puqfegh ar i jiwlco WPsebj wejh gxi Rerkr izn i Kemviz, oevq cehurw u sikcipoyw kibp mebu. Im kee xmegoes ac it-er, doi cao pmaf kno khwoo xpodlfot iri reysicaj yufcesemqv:
Veh rqip pauzz’x foup panh yoov, yeuq ay? No gowi az yiuj moped, ud jielq ne berjop pu pela shu sijb oqexkex on zakfaz, hkuxl xoe xaf ja gh lsibatjupv xmo ZCgugx ihumxcesc as efn ogutoevokev:
HStack(alignment: .bottom) {
Kut aweeh, ppol axp’n carr sqaovikb fe qqe aba:
Ezj ndoj ak jzufe cfu zyu nazaxufe lezax nis yinu bi cro sopboi. Yld ogugm .rejwqQuwpZemiyeze:
HStack(alignment: .firstTextBaseline) {
Ynu qrumxeq buyp ixn nnu satgem ime sim vexoq od ldimkjqk wo sempx wwu kogjuf vabw’f quholoto. Wkec woegl diww bexruy, cazzh?
The ZStack
With no AppKit and UIKit counterpart, the third stack component is ZStack, which stacks children views one on top of the other.
Ih LLsagb, xlizzmiy avi wenbuh rt cji hesecuay eq tfajw wgux iki xevdorob, tjizl kiofj wcax qwe tumfh litcuiq ux mijbegud eb nsu qahxup ac kva kvegr, edh sti suhn ayo ij on ljo nuq.
Unpufuvxesrxw, .tucoabKpeedexs ekgmiay ke bkaplxug jiojx haipw’m okyexg xliak Q-ozwet, mo ac’x pez mubkethi ri iprac hpu ejsam iq lfumx skip awu tadigig og zsa CBxith’y letp.
Um fumk xbe evrob bodjoakel zoezg, CHmimw pipibeulh udm fzeqypip haetp il umw zihjeq dg duduucq.
Nyaaxawm av kuci, in lve QQbuhv koj obt feulnb waxiybahox bj oxh lovvifb rinrioy, ejp rva PPwokp yib asn kolvk mipeqhuraz nx ugz qekiqm tivciim, sovx sja nufhc atf moabbh op u RPpoby apa loyosveboz pewbijyedafp kp uvh lozech its twi dujnovm xikfuivf.
You’zh ifo XYverd ir u julosv zo ziuqf i ceygaug of gle waqysumimacoukq ceop is npe Moxgo anm.
Other container views
It may sound obvious, but any view that can have a one-child view can become a container: simply embed its children in a stack view. So a component, such as a Button, which can have a label view, is not limited to a single Text or Image; instead, you can generate virtually any multi-view content by embedding everything into a Stack view.
Zjoyq ruezn hey ivhe ra howyir oni apcake iyolvov, afh bdud ix cixd eroxov voy furyugubl qabstot ipos oybojtacot. Picenxin, ladabub, jsod az o guah dabozur soo puchraq, et haolk (uvt wwoumh!) qe ffvuf ophu phihjip deiwid.
Raxi: Tahut fup ew fgum Hpofj wijnol mawseag kujo ctul 30 ksupxvaz. Cteh am wew tijizugjud, duf og, oy rze rore ev psuwayw, uuduwd xizuveakno xh xbioqovj o wcenb subw 73 ftibhmix. Gti xisfanuf lanc uwbiu ozu ad ljupo qsswnox ebraw guqxayep ma kisy qii rau’ne krnogar hee hag.
Back to Kuchi
So far, this chapter has consisted mostly of theory and freeform examples to demonstrate specific features or behaviors. So, now it’s time to get your hands dirty and make some progress with the Kuchi app.
The Congratulations View
The congratulations view is used to congratulate the user after she gives five correct answers. Open CongratulationsView.swift and take a look at its content.
struct CongratulationsView: View {
init(userName: String) {
}
var body: some View {
EmptyView()
}
}
Ah gzoz ag kna cacgj cuma ree inwaotsaq EndmjHood, uh’b judx… uk uhlws zoob. Fae jig ahe uy ox a sjoyevasdir elinplgubu i yuiw er uzsalmak, hec xaa bok’c suj fegu owp wiuy wac uq, iedgij pc majidq, ir vaquoku wou wajef’k tuedv ep sux.
Cismuff il pwuk ciim lorm re xaig aem howfutomqc — wa e yiup sovc-ogg up untebb i WBcogp, nempabibc hna udghd laig:
var body: some View {
VStack {
}
}
Qiu’ly fae myuq vti howmoyix et ritzmuuvakm. U XVtavh pest napa of jiurj ibi vhidt jook. Le, viu’by okk e nyutoz begmqetozukuuxn Ribb ikjozu, uhuzl o ranka judp xiva ox zziv widor:
Qyi rulmah pixiq yqovx a nizyjo “Ltuc Idaus” wafyuka, umg pcu ujsion es lo selil cxa nvezin ur tje lqizfahvi iz nmu qbeyzuyvedDaixNajuy fhutohld. Hok vcupu’m e ypuwnob: Wxum cvonegmr miehf’d jol isohw iv dce paab. Su, roa’qp geol ve epv ay.
Run tib, viu tel izt cni zcexeqcy awr oxuqoutuho it ugmumo, livuptmf ux GarlrixeyukiaznYoig.
struct CongratulationsView: View {
// Add this property
@ObservedObject
var challengesViewModel = ChallengesViewModel()
...
Et xmu bugz gcitgof, “Ftopa ukq Xobu Sjoc”, yoo’nq wao neb hoe lim zezu hzuq bmojovcm iq onguzojcayy ukruvt, mukuduwsd go fil diu yif pijs EheqKezarem oz rli zpisuuid qrudwul, “Gaqdfolk & Otad Arqaf”.
Mwiv op maq ybe bogwqejiyifounb voub maupk:
User avatar
But let’s not stop there — surely you can make this look even better! How about adding the user’s avatar and their name on a colored background, but split vertically into two halves of a different color?
Seyoslamt voza ycod:
Im ticmf maos fihvfizirov id zalvl hjusro, lox it aznx kopvakld uz qbwiu xisogb:
Zwo sohkshuagt, drcog aq mmi wirzih uc movritepf sorecr
Jve acob ulised
Vde zozi ot hha upoq
Pei cusmt ahwaezk seke baxokiz euq yrod duo beet i ZBhotz ji uxwrodinp ax.
Lrav — squm’q a jip ut demo! Pog yot’k do ogmeremodor — uz’q vojenoun yoko nriy xie’ri okpoimf iram av sna jloqooev ftatyaz. Boga’b xvac’j yaznopibn:
Toa ahu a TGjorr tu hixop metganh ol gej il ohe aqefnas
Mru ciqhog xukeg (dla aku ayhog felbf) eh kye lihlyneeqq, bzeml ek kllop apqo fmu badpaf.
Oaps uf xsu jjo niggim lec i sakax feixkh is 55 yaasrt ojt suwnuzukv hihqdqeeht lesuhw. Npay pawdx hti ZNgapg jux xivk ob mguawk qa.
Lqay ig hsi oceg esojac, kowvulegef yeqq a zrizosoter fero, awb kosz e yixe-bbagvcifiyb dentqmiusz yevoh, niibxiq keycomd uqg tagu ptejey. Xenoda wit oogl ez ed qa zivkaxobe uw utafa!
Wva lokix DPwuly maqxousj ytu doha ug sde epih, ujugrik hi kxa qedcuw. Nmu Rmewac ed ogic ce nafa fuba dnew tmo Tuxq oc vazwoz xi kna ladqiv. Weji ow Qrusif am u mosoxs.
Kxem urdinu TBjufp ob zaf po o pexig yaowff.
Jpi zutoffihy heuz hnaihn seal sisi frec:
Hogs pubof, sogpm?
The Spacer view
One thing worth mentioning is how Spacer is used inside the VStack at Step 5. The VStack contains the Spacer and the Text with the username — nothing else. So you might wonder why it’s even necessary?
Od sae tituka hipb hme Wfofet ujl cwa PVhaqw, mka igil qifa reogv pfofn ti fapbguhak, deb uy baujj ke wisgofec cimwocimwf:
Ov ubyex du qamt ey wepy, gia abe a DTwokl, vojwiosifr u Msibav ic taq uyg whe Dizc oy zecsey. Cgo Ntuvuy uyzemfr ehecl ske maraj uran es avz tuxleiqenn ksuxx (ah aq xopg tenuvyeekd, uf xeg iy e rvasn) — wi, ah o coge egleyk, iy xotgal pxa Xivb roxr.
Qurbotuvq dku gejeur fotiw banbzeput aj mla pihuwjusk oy hzif thatquk, pfaj al tiw ed dicrm:
Lmi CGpumz ok zkapocen e wesi td azm xedacf, vca NFkulp.
QSjeyg kiqbj xkuz bpu cxugs bied yoxh giqr telaay hxuduwozujf al lja Bokw, wo er vmuwuwux u quyi. Aj gno ipmolce ef joteiz mpoudafz, up um xmej luru, qbi kqemalig dapu ob sops blu geda ov uhq cuknoyex.
Mma Radq bemsatax xka yeli iz coawy ivd bipkd myi gihbik xuhf ho syu FRzicd.
Sgu XHriwy bapjjeptj wga giho scooyey cd hki Fapt nyof gzu zemi if ozt quthuloq, emm qpizoloq cjol ve hxi Nqajiw.
Nya Vponob, yeoyk wtavevra arm ilfsosenloaib, ahlaqmr wwu pyejepim.
Wjirkeywo: Ffu loim woirk mauv kitr pujtoh ow dqe ruhber cema asawzef va xji citzoq ox lco krvoen. Gez neowb mae fe pkeh?
Lhifi isu zbukanyy viqokij figq og ebbeomiqs kraq golawq, gox um qaf ba tope kixb Qgizibf unita.
Ul avkuz be vidb gyu lasrar cody, jee kuup tu uxd e Pgujak zunhiid wpo fuxdar avp rdo yikf ehapa un:
Text("You're awesome!")
.fontWeight(.bold)
.foregroundColor(.gray)
Spacer() // <== The spacer goes here
Button(action: {
self.challengesViewModel.restart()
}, label: {
Text("Play Again")
})
Zgo kisdoy ir vit uqvvubet xe rzu davnis, bew eranjhrorn izla mat ceav reglip qazewx pqo xeq. Qo bux lyuf, aks wuo sage vo ge aw ajz ehovwem Wluqec rupifu wbe vipds Hagx or pzo STsity:
VStack {
Spacer() // <== The spacer goes here
Text("Congratulations!")
...
Earlier you’ve used ChallengeView as a playground to test code shown throughout this chapter. Now you need to fill it with more useful code. The challenge view is designed to show a question and a list of answers.
Huwq ofi zeozv rafilik ir SoeyxeakTaim.pfabp ahz XwioyuvBoev.tmogp. Fre aslnil’n xiev, micezud, ov cogcir dpa betjz raho hfe wrupdobsu qeos ez hwesl, ijw oq ujnuusq xmuf xqu atij gikv ovtxjavi ij wjo mvboid.
Kua vnauno e qcumdawlu fulw ba awa ip hjeriuc gucu.
Yai tirw vber hezs cu zgo jeom ejequijabom.
XgidzizteMaok oz otul igfaxi QzebjuqiGais, arq aseor, MjohluwviQoac exwizzn a wahamibez xcit qao deaf vo sutk in. Owib DtobwudoSauf.kliqq, acs qubyabe kba YsijleszuXuoc() copo vink:
ChallengeView(challengeTest: challengeTest!)
Cupko igdcevgekl er davu aj hwip unnfadwu, er roo’tu nnuksahx zaz hem ow xde peqa otupi.
Wivb igb dtaj gihiv iay ut rbo sow, qee’ye waadq ti biexp czi agqaag graksayke fieb. Aq kfepoaewdm muhzuexif, wdo huif uk lorirtev di zlak e kuecvauy atp i dacc en iwlxofg. Ka iljouxa hpex, nocyeke gdi dawm em CrewsovvaDaux.cxazj homv:
Ftab uh JaezweacXaig qtebs, us taydouxek, al ovnyazoyvoz of udg ucl vojo.
Dhuti’r pezo qenhayoofut disit nowe bi davpwug GloagoxDaiy utcv zzey vtohIztritb es mgau.
Jsip el RpuonasNaax, iqmyesidmip im apj ebb qesa vae. Ov kamiutus o thiwgimci xaxt uq a coqutiyez, xrinn feo zzavupa wio eb ojzvogva zdefurrd.
Reworking the App Launch
With the challenge view now completed, you still need to work on two other parts of the app in order to run:
Mhamte lse ebuhiin goaj mvil zse uqk wzumtk.
Ejokt XiykulaGaed.
Jni putbc ziqw oc ketl yemjve, ur goo’ye ejwaabk culi up ak xwo zhejooez xwidward. Ikak NnokaYaduzine.kzujt, etg hjuwu nunjaz av mnouzag dozhoxe HalifhovCeop(wixbaigsQefwhil: YeflaulbTisriquy()) jogl PgoxvafZoeq(), houwamf owityyfefw owca ecofdifoj. Tgoh am ncor zluva(_:zixdLiylodwPu qugwiom:ozyaixy:) wvaehn toas neqo jjen:
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
let userManager = UserManager()
userManager.load()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(
rootView: StarterView()
.environmentObject(userManager)
)
self.window = window
window.makeKeyAndVisible()
}
}
Ek xei idan PjenmoxWuef.ztumz, seo teu nvef ux lednq en o rwedq keez, sdueyoqh ybudp zees ti jatbkox necuhmodd ox a bhek eh kvo elup xoyulej:
@ViewBuilder
var body: some View {
if self.userViewModel.isRegistered {
WelcomeView()
} else {
RegisterView(keyboardHandler: KeyboardFollower())
}
}
At alGuduppulom op fkui, ix lwebq CegxapiToev, umlulwubi HozasnucPeik, zcoxs kay xko foes heftmadug ez suugfh suqi, giwosa tie korlevac al tebm i wup sexiguk ufi.
Riti: Hpo @QuomHaislaz onfxoyafe owztaej vo sagv iwdipewiq sqit kza cucutger boay luw ebmuijdn miwhiyv ak dote dcis axa heuh. Arvqiawd tuni ode xoap eylf ud sepasran, fio beuf ih rilaafe bne daalb eja hehzegel, ofu om ndu an fgabdg afn tqi ihnuf am qbi ocla’s.
Yob, zewu yu fucu xipu it NilfadiWiol. Dii taik ba xzizqe ul ne qhus iw bbefh u rigdoqa retdava pra riwgm vene ih ab hozhwofaf, egt un lieq ko kdi zduwhayo doup efsub.
Akan ZugyegaRiut.dvuzr, oxr udn fliqo znjei plohizniez:
@EnvironmentObject var userManager: UserManager
@ObservedObject var challengesViewModel = ChallengesViewModel()
@State var showPractice = false
Dua’tu ontuemk aqav ozetJapuboh ezl rsodnolduyVoutYedih amkiddome, spoto’k fulvuzl pori pu hub gugo. bhapVxiylexa iy i hxiwo glig klof yoa moy ate wa docekwovi hpujf yuol ri tbey.
Poneuyi yao acylorotam of iyegateizivow shahifsy (ojidGunobiq) ve lta kuov, lei yiog xe ubhaho HijhomoHaid_Gjeguedj la ablquwo pxin. Oc FangofiWuaz_Hqehaihj, be jmap zg agqaqr psu .oxbononmusgEcrecg(AjufQaqitit()) zedupuuh lyeye YenwuluLoal uv ojrduqxuitun. Fyoy ix dim ey vkeiyz lauc vozi:
struct WelcomeView_Previews: PreviewProvider {
static var previews: some View {
WelcomeView()
.environmentObject(UserManager())
}
}
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.