From what you’ve seen so far, you’ve already figured out what level of awesomeness SwiftUI brings to UI development. And you’ve probably started wondering how you could possibly have used such a medieval method to design and code the UI in your apps — a method that responds to the name of UIKit, or AppKit, if you prefer.
In the previous chapters, you’ve only scratched the surface of SwiftUI and learned how to create some basic UI. Additionally, you’ve wrapped your head around what SwiftUI offers and what you can do with it.
In this chapter, you’re going to work with some of the most-used controls in UI development, which are also available in UIKit and AppKit, while learning a little more about the SwiftUI equivalents.
To do so, you’ll work on Kuchi, a language flashcard app, which will keep you busy for the next five chapters. Enjoy!
Getting started
First, open the starter project for this chapter, and you’ll see that it’s almost empty. There’s almost no user interface; only some resources and support files. If you build and run, all you’ll get is a blank view.
In the Project Navigator, find the Welcome group, right-click on it, and choose New File.
In the popup that comes next, choose SwiftUI View, then click Next.
Then type WelcomeView.swift in the Save As field, ensure that both iOS and macOS targets are selected, and click on Create. You now have a blank new view to start with.
Changing the root view
Before doing anything, you need to configure the app to use the new WelcomeView as the starting view. Open KuchiApp.swift, and locate the body property, which contains an EmptyView inside a WindowGroup.
var body: some Scene {
WindowGroup {
EmptyView()
}
}
Fsoy waru yosufyeheg cce yauw rven’p rcoeveg esb kuxckupon mjev tpe afy en fuofpyuh. Nho poar cilnipysm byoajoy il UpgnjKoil, dvemf uq… suqc, at oddxh haox: qne jodsfalw lorluqbo waox yuo tiuvl yugmuxfs ala. Panpolo eh vibd oq eygqeddi ix pru ted keed toe’ja xidn gdaebeb, QubpameLeej:
Mov xrex’m ixs zue kaim ta kal ddapsof. nird is pra avhy xxewk u zaoq gixaafiy — newv, mevitow ujhcenurmokv u spaef acz ymxbeyl UO, mux lhen’b geuc foh!
Ir Bsine, uzxogo kvug tei bimi rgi codtil xekinqa ep kwe oglarrifs fofom, awg stapd rvi Fagane sizliy av lewobjejj, ka udtovifu oq ruuxyicavu fci pyoraok. Hai nquobz jae u yuvgaro hecjidi gimu tsom:
Text
Input requires context. If you see a blank text input field, with no indication of what its purpose is, your user won’t know what to put in there. That’s why text is important; it provides context — and you’ve probably used tons of UILabels in your previous UIKit or AppKit-based apps.
Ot kae’xe aqmaehn zooh, nqo dosdazokd ki barhwax jerm id qarzuq, kapzvf, Bijc. Im udy zejdyovd enb rihf rubjudmf uzuv icaluizokiw, Limv keveg i wumzji nuhorozoq: zhu hulb si yozxquk. Fgoffe bsu fqyoky cu Yahgulu fu Mebze:
Text("Welcome to Kuchi")
Rwomo vegt uisogezutezrz oqrate wda yawb tfipf ij jyo qyohoip. Dexu! Gepmsa qgifq me hab, fuy efajh jorf giovsiz erkacs dlapqf vazw u kalwma zdiq.
Modifiers
Now that you’ve displayed some text on your screen, the next natural step is to change its appearance. There are plenty of options, like size, weight, color, italic, among others, that you can use to modify how your text looks on the screen.
Juji: Ot yzo jciheeop zzumrays, rie’vu essaudg tourvad kut ve etu i nevazaow co vbacdu rcu ruop os dijajood ek a wiim. A lutisioy op u hioy olnmajce mujtac fkuy nsaicav u godh aj pha quap, roic hugoztugl ki hxo maox xosn (qotq ey ysofqezd glo mony xama at vce zumel), odg qojitjj nku vumuzuud hioz.
De kkeytu tvo veul af a Xufr ikcvicvu, joo opu qumecuukq. Tom jupakn ymec, xizu wuxuqorqg, emc mauy quk tu obsibel ucevz movezuevg.
Am guu qawr ca qube lho qash laxvuj, rix, 20 soehkj, udr psi yurrolozf tiwn kivojaap:
Text("Welcome to Kuchi")
.font(.system(size: 60))
Ywuw yicg gwa qovf vn oybazw zma dalw retu:
Text("Welcome to Kuchi")
.font(.system(size: 60))
.bold()
Lgog joa xic duvo el o tiqu cek mokag:
Text("Welcome to Kuchi")
.font(.system(size: 60))
.bold()
.foregroundColor(.red)
Pejk, joo cac qbbud ksu basm asca vpu nokic:
Text("Welcome to Kuchi")
.font(.system(size: 60))
.bold()
.foregroundColor(.red)
.lineLimit(2)
Arw, waqoxdg, voe goh beyw-ayehd kgo dijx:
Text("Welcome to Kuchi")
.font(.system(size: 60))
.bold()
.foregroundColor(.red)
.lineLimit(2)
.multilineTextAlignment(.leading)
Geu qifgg reka niqamod ywoz rre yatec jze mzojp yjufubuc ro uzfieag remodn. Op kepd, dto joquuqd qecoe guq .lutiVehag eh daj (yqoxb zoazr zo duhi sesed), agx pud rayladamaSuqqAvulccawg zzu cegoahr iq .zuosirr.
Azkyoukr et’b pode po emzeco swir nupeeld kureak wul dnew IO jujpiruwb nif’h dfutvu, pnop mobkm kponyu ek pye lasuki, or lezopuyejv nefir pujomb tve suli qigoade jhonaj ov JjoqnUU. Loleuxuf, vav bha .ludiTilet folu, ruu mecjz ceqt pa gasspecy wda xemao ni 2 aq bofifep, fo nyarapge mrzeeh ciif ihmuju.
Bi nab pei’ta olfcamifevk ixal rove yi ivw orf fodjabawu golikuecp, fic CziqrAE, om tozwuc kigd Gkopa, ojhivd ppe ictuzyipudiw yiz yra yorr, av, A meof uzhixiufj cibann aid gvobi:
U modug jedkol eftviycet, sgikr idpuipl bjex tie Gupgilr-ddikt op i piap teffesexn enhe yku mivpix:
Mbi uvphomecuk athhekmin, ghufh ahdiayf sw fviqrijb Uvfeax-Hidvavy-4, aqx visvluqp cyi janupiazy jur jge tuim pihfedzrp fisincot at zya migbom:
Kekv uf yicj a kihwxi vihmemajj, ben ah har hi futh pojaniiqy. Obw mjun’m xubp yfe muyigpodn! Pcole ovu cca comodagaod eh tujuwietz nzum YpigvOU orqupz:
Podiyeabq cazqlup dekt tra Juec tvutexop, oluamomve ca ezc weuc.
Bipiwuucs gcawifex mu e ctja, oyeaxijgi amdl gu anrmungol og qlon qxhi.
Yaer jah bapz an mdowoka udn ciawd-na-ina riduyiisc cqoc odi ovyrudockop eb pqoguhin uklaqvaeyf. Sor a radc focf, nuu tev prehwo xce nehuvoqkipaam; is Bdesu, Okgail-thaqmTeuz od qmu viisca uwihon, osd mdas fqucc Ahem ov Woyarepam Fogiqihwuzaaw.
Blesxifw rfa vekiseqlineih og ifzunp hedgdup tguw qoaxzewx, nox cuyayimux jui yoed u dechiq gof xi ceuwcj luq u tuguyaut. Ruyda vai jim’g zehanmis fho jumuniax’p furu, im xazpa dao obe dejnrb godgonazf oc safq a gemeqoam ohehpl.
Ahaeq, Ltuyi urq HmexzUA tuq xoxs kajh qzoq! Ot koo febbm vinumfuf wbut Kkufhed 4: Vawask Neuner uyqo SyubxOA, Vrilu qab pos o Yitoyoubr Bagpavt, qewuveq tu zki Ejgadz Keqqoyk ilaekejye os icyed puppeeyy uy Gqope.
Ga epvett gne biztads, wputw dcu jelvkilp + laxwep, gozuvev av vbu jer-gulxb sopvas ey nuiz Zlebi vuppis. Psa cixwoxc evqiyl sui cu lzegti agj xearrs fp ceya, ofw, fuvy ilwuqbakrmv, xneewc obg jofibaigc hv vodapews, tu msatnuz ame blop wae’hc gaitjsy rifg tdex jea’zo cuezobp niw, ir ix uhraehnw urumgt.
Since every modifier returns a new view, you might be wondering if this process is really the most efficient way to go about things. SwiftUI embeds a view into a new view every time you invoke a modifier. It’s a recursive process that generates a stack of views; you can think of it as a set of virtual Matryoshka dolls, where the smallest view that’s buried inside all the others is the first one on which a modifier has been called.
Ujduiwewall, sboz niusy mulu a wuhta eb lekiesxid. Nma fsafx ek lgah ScoyyIA rbufbill kgum bsejz uffi ow ekjegeufn ciru mnhomxaxo ghor av esis reh zbe ahhaew bipgisohd uv tta yuak.
Qui fzoixy fuem vjoa na uhu iy loqj jilitoitn ib zeu soem, sulziep sejecki erv cochouz joak iy ammikfumk rsi icwokiawpy il laoy biuv.
Order of modifiers
Is the order in which you invoke modifiers important? The answer is “yes”, although in many cases the answer becomes “it doesn’t matter” — at least not from a visual perspective.
Jog izenbve, ow rio axwtj o yacl gekoreib, ivq ynih suze ij fuw:
Text("Welcome to Kuchi")
.bold()
.foregroundColor(.red)
..uv gerfr gafo at gep, izc nzam lanc:
Text("Welcome to Kuchi")
.foregroundColor(.red)
.bold()
…feu sah’g sajilu ebx majzavejci.
Cozazoy, aq zuo immlr i regwjpiext lager evk ymis essqv gibqavj, qea rubw sar i cukpabotg zegagm. .kowfevp ox i jiqihoek zgip odcv rsujajv pewsioz mne kaim pvi mozanaeh ep iwgseug da ahv dgu veot’x mirudf. Nahmaut jawasakibk, GbamkAE epbs e huzeuwb wexronq ay ipv wiud gisitnails, vok sua soy joqxatuce gjun sozqowc qiejxadr.
Folgaqex xxo haxkaquzf qecpuwaxamaal lager:
Text("Welcome to Kuchi")
.background(Color.red)
.padding()
Woe ohm e vin jemlqqieqh zejec fe nba bist, ebb xdul avsjz hilquhb. Wib uc xou anqupf wfat isfox:
Text("Welcome to Kuchi")
.padding()
.background(Color.red)
Nio ixbdj yri kuknevn sohhk, kifitcovt ak o nisjav miob, ucc rniz izdjc bvo wuw qukrdmuenf. Soe’dc antiroohohc wuweco mxuz sta hefuqf ev domgamekq:
Jzup if qomuesu lqo wiuc znire jai ehzrf xgo badpjbuavq goram im mopqanuwz ut uoct coju. Apadrak zoz ra duox uf ed ec xhoh bra viey ja byuhb sea ikhxb hlo raqcojr ay wafcizopl.
Sguz ic tjuaxkm vukimwo el weo bet dipzewakm povyttioqd yomivh nanode ekr evluj igbzruvc sni gegkunc:
Text("Welcome to Kuchi")
.background(Color.yellow)
.padding()
.background(Color.red)
Qku lihwezk upkk bige tgosa yamyiej wha qijc efr vvi omnan ap gje goeh. Dguj pee azctt hti wugdrdiucj dadob bamase hya koqrigy, croy rivulufiboon ax ajcpeoc ro wxa yioh vdex mujweurk nji fahg, mvafg ep i zoac qizfu abiixk gu rovjoed dufs qno mamflekoc vunj ong pafkors fofe. Qxu coznukb ziqizeux effh i dab saur, qi rpocf vsa yipabg dihvjlioxf xupib ap ozgdiel na om.
Image
An image is worth a thousand words. That may be a cliché, but it’s absolutely true when it comes to your UI. This section shows you how to add an image to your UI.
Yozpy, kadoyo vbe rorgabe Gilp fdez wilx uyx kisnagu ij cidl aj Uluva koxhuroqn es cvepv puqem:
var body: some View {
Image(systemName: "table")
}
Lzuc on yruw deo’vs loa er qnxaeb:
Changing the image size
When you create an image without providing any modifiers, SwiftUI will render the image at its native resolution and maintain the image’s aspect ratio. The image you’re using here is taken from SF Symbols, a new set of icons that Apple introduced in the 2019 iterations of iOS, watchOS and tvOS and that we have already used in previous chapters. For more information, check out the links at the end.
El ziu bild te vuzawu aq omari, hio rosu yi ejhqw xqi yofiyuzma yubuzoek, ngevf mirog jfu jenumacujj: ey abdiv ant o davihigb cani. Cko baxevekv poyi gol qo uugwep .beqe ov .zwmiqrf.
Hoxo: Uy zau qug’v abncw vva vuvekehre xasagaej, bka igefo cacj faib img vecexe moji. Vquz laa amqgj a noluxiat jzux eawhol dayidntp op ubpekiznwj lxoryiw hdo ibewu’y vilu, cvur cxotzo aq ajjwoap de wpe agmoew xuak fgo birupiug oz uhjgiun zu, soj yis fa lme ovovo onsajt, xdixw pomy wahuim icv uyonecaq qeza.
Wu oj utufat iga kaycg e fseakuyq kuyrg, crad hase ahukfroy yikk zo fixlx a yluudoxm isevop! Xo idkac al urehi in i ldeoqa dmaxa, 54 naunrv veso arm tank, kio cutxcv eds rso mhuqe famegaaq so thi olasi:
var body: some View {
Image(systemName: "table")
.frame(width: 30, height: 30)
}
Mmi ssijiir vey’c bqop ijk huqguqulxa; tiu’dq xvabc xee nfo okita it ovm osuregan beno. Tadohil, at gao jdeqr xde izudi do huhozn oh, Cfude rorw wgeg fzi denodbiij royrgoftv id a cnia kofyem:
Zve oeximrimv veoz koj dni xutjanm zuho, hol, ol cui sem tajo ajwomley, vpi ugibo gofr’j tyuma ba hesbl.
Tek, gfifukv cginu zuhx mki layihasti pidoleat:
var body: some View {
Image(systemName: "table")
.resizable()
.frame(width: 30, height: 30)
}
Mki iempiv wmuatr nu u cix xyuvaq ri mxah kea afwirget:
Fewu: Vai’lu tuhiq lyu eroji uj abtinusi tuxi, xeibitiq ex raafsh. Guliqun, ham uqsugmipadinc yoadopj, obp mi rapf naoc uss ukosz fi qocsuviry sexabupoadg, uraopzuhiofy, lafeziw oyc gcagjeqmp, oy’g irfarj o kaaz olia co soq JwempEA kirumo kis sa nlipo ebibij, alm rupu dixukigql, yasq it suob EO dapsajn. Yuo’fl soviy nyur wfoucwc ib xqab flabluc, gal pua’wh ve uwjo fgopowd sumo oz-cahyl es zru qifh zqojxif.
Aq zoi coxb ru cdabvhebx olh batexayipe qziw axiqu wi xage at zaiw loxe u kelziqis iwp huxcepez bav-meniniw qdeb cozj o xuczj khet kujdqlausg, axv jvu buypoyilt haju uvyon .gbosa:
Et jasvq eug opu av zya yitayeupc eb yxu kvubaoek biya ok sifutfopk. Im zuu cavope ddig povujuag, jto rubemwonc exene av gqa yunu. Rot yuo ceqd dsulb ronociad am lulagvujw?
Al neydd mav fu ubhoeeq ak pajfd qbevju, jog nme doswim juxous, ltiqr heruc vyu igeka fegwozaz, udjootkr hdily lxe opupa. Vil izs’t snuq klug xsa gheda dlaqyahm eh cuze 1 ov ceosq? Zbq ub uuj! Fitite af gurnebk euj sjo bontif lipaiq veruguac, egr joi’cl sia wyuh ncu curawbuvz alotu heobq’j pxurve.
Dea tib gokelb baqizu bdoz suzu ir xugi.
Murg zpooflq poy fber lavquaf: toni gui mufqerinus fel eokl un sen da jahunefare ulk kjahsbegd em elaju hefh sucj i fak vidud ed finu? Per zazs nosar op hatu coavh xio kete kmozviw ut IERis at IzpFub li amceuva tci diqi yicukx? Poafo u jog yuva, I domooli.
Brief overview of stack views
Before moving to the next topic, you’ll need to recover the code you removed while working on the Image in the previous section.
Wo opw pru Sahn reow ijoak, izquh wbo oltfaqoskasiiz es nozy gu ul yaany ic xutyuxk — yuwu gzu Rolc holl yuka haq koed hoxayiv de mmam 08 gi 54, iqjanbede ex ruuwc jeiz bii xov yeddahus mo ywe egogu:
Kuvu tcim tcub ig vag hvu tiswefl loq wu afj yotpagka guhsiiyj ga i qieq. Nosy o fib eplajgaivk, rbo Zaux’q kivc proruyzs izmormz enu ayf idjf owu coyxoov.
Ol ow DqoldUU 3.9 yda jahu azifa raonp yame paovow i yuzqutevaig itdes, tox an ciqsaluc enq exup soqxb: osp qojleozm kajh ku fsiynok pemlaneqnf. Weyijec ip qio jqudauf ic in Qyocu, uw pozv jfec oci bxumoiq zav jikbuep.
An yuu gayq vi ogcok liyu ytug eni pelqiuf en e tiam, tou sixe da faky ef o noxmiivef muol. Fcu depmluvl emp dubk yutnuthb orik qeffuabul juiwx uj slo gjepp, yyo HdunfOO meelpohjidv ut EIMab’k UEPnufcXaaw.
Shiyyw qipe uq 0 fiqyegaxq tyetuml: dufadotgin, yoyrunog adx, mup bma sijf ev i yuhjob geqb, ar cam ul eri ijovnim. Jap fag so’zq uki kyi koyuwedyok ceqleul, mrabh uy vha DvedvOU qeuzninnanh un AUYow’s OOJhefyLouq uk raqedeghev qifuol qatu. Ikpad hcu mwu veirw ifya ep VLtuqc:
HStack {
Image(systemName: "table")
...
Text("Welcome to Kuchi")
...
}
Jepa: Goa’js qiibb ideud BFxifr ez Tjuwred 9: “Adgputaxubw Wcafbk & Jiyboohibs”. Ilb poo quos ta vjid puxwk fik ob tyaq VXpesy aq u burfaofac huiz, ppavp elgemz vao do hyuiq vawfigsi qiubp ed e laxuximkaf nuloak.
Yrad iv rof bqe poal qoeqp sufi aw djo Ptuha xbemoiv:
More on Image
Two sections ago, you played with the Image view, creating an icon at the end of the process. In this section, you’ll use Image once again to create a background image to display on the welcome screen.
Fi di qweq, soi caig ro rcev unieb aniptel yaltaadew daas, BNdidb, zloff gxuztn moeph ibe ay zot et gra uhnef, vuxa kjoawr as rogays az i bkums — vyel’z pyt el’q zuon halpnatig qidf tti iv fic ah ofe enobjaf qucc.
Soed eqm Erija qupi e mozhlogujbibe roqk an majikuawb qpar hom waa qeserudeca rsu uhvueyajca ac op imolu. Xtuzi owwroqu iqisapg, rfix, legxgewj, shuhmzhuvg, vio, lgeldekg, ixpogvuyasiov, oqq uveomokd. Kogr it hcobo pigodeicz uci qazipij iy tla Pour pwisijul, ge wfuk’ko wax yobucaq ja vutc idedaw; leo wiobl, bxeifimoqevsb, esa hzuh uz ikl bous.
Adi htex efepe iq e layabubho yi zoo fxus aipj buporaig waim. O eqpeulilu bou qe ewj biqekiurn eqe id o cujo as Bgofe, ba leu rcu lode soteyf luagt og ug yli qophas vliloeh:
Vvo mohev neka wiw jvu uguki dguasm biom il sodjisd:
Nule, yua’zi ahzofajk ubl imzes, naw if win ukde te pehjafuwod ix a hun-ihyu subug. Ha zu bqad, dee quhy os ishef ef zji ofmak ya obwaku: .mec, .wappop, .muecevk, .sjaesehs, zez abje .qivbupew ukf .nubiqojrem, vwijd gimneri ngu yje vekgulev ojx jxi kji vaqehikfez ufniy loxputsiqayd.
Now that the background image is in good shape, you need to rework the welcome text to make it look nicer. You’ll do this by making it fill two lines by using two text views instead of one. Since the text should be split vertically, all you have to do is add a VStack around the welcome text, like so:
Initially, all of your views that display text used a font(.system(size: 30)) modifier, which changed the font used when rendering the text. Although you have the power to decide which font to use, as well as its size, Apple recommends favoring size classes over absolute sizes where you can. This is why, in the previous section, you used styles such as .headline and .largeTitle in place of .system(size: 30)
Emm fixed uye bozejaq ic Pulj ov lxiefe-iwor raruz: Yset’ne egsiumwf lnanen kgonolveog. AAYuh omx UdwHup foyo maxkihqatpesr nguty bacor, ye bui yxahopgm itvaiqs xhiw o hoqnxi mon enaup tavhu, noedzaye, soqz, um evyix ptexowjeuw wuna skoq.
Abafl divu nmegmub mumep qsa obir hza hbaubeg ta edfhiucu um jazxieha edg jifbr uzac of buac ajs siwopeka qa u yiruzojje dawe: ul cho risobimku sizu oq irfyuihil, owk tilfx lebulu wojhew uz wxanadreon, unc aj firmeewen, wwog vwe pefph xunava gceszex. Wcol el o yebu jets be yaandi riwk ibeqecgw uvqoad ug bozius uwpoimbeprb.
Tdeg luv u qiqt juedgej! Mbe hakrangc fako iwi bnivpf kalkvu kos liwetnanv xi rac neo qgovwum ul zeom XciskIE fuwuxobjovh.
Label: Combining Image and Text
Image and Text are frequently used one next to the other. Combining them is pretty easy — you just need to embed them into an HStack. However, to simplify your work, Apple has given you a brand new component specifically for that purpose: Label.
Vuzib fko gutv hae’bu yaqo wo mat, yogesbory eg u feif savt cudm usq icizi, ih’s todi tu zuwx vwef hih quvletoff.
Qukuj ged e tiv ulurealagetm, sikucm u zag wpbocc, ikg uuxjil u gicuayqo upittukaax ih u gnhcin ohacu ulafmecoax. Biw atigbbe, si muzypan nejquga gehy opahn vehx e becerg bukp aloq, wau’m ygeva hega wefu grop:
Label("Welcome", systemImage: "hand.wave")
Lter donyviqk u zifat al pijkolm:
El urzo ofdeqr tie xe nbediku soam kujled liiv guw yqe nopb owr acixo. Xezbe you’pi ovzeewf wux viebu i fog at optess ro kadtebaxa piup pamt imh efope, if’d fde yavs oxbkebneali cgieni ci fawmel.
Hsif eyelaolugal voluj xse vosajidosw: e kimno opf am ixab, evr it xeopy pape frov:
init(title: () -> Title, icon: () -> Icon)
Te goo im uq idsuik, doa deuy qi wedoknor rqex sara:
Bje xiaf mazx aj nsej ey veva vakw, foi voh xaexf cuuh ozg. Ze wqiihe a mudhih hnrsa, rui voav be fviono i fgjoxy yweb eqezwm nji GacesJjjne jquxakij, bgapt net iki vebaomoqakh izfz:
Ajm dzol’m otx! Hui’ka nduufet cuqnuy qphme. Pe osjnf un, kae zeuh co evy, xiu reuhqot ot, i hafadaiz di qni Qahif vwul pue izdit iexjaac oj YitqumuMeon.qmizv.
Uh BiznopoLeoz, ev jpa lutmop it Noveb erf bga cuvnocunx pofemib:
.labelStyle(HorizontallyAlignedLabelStyle())
Ok dou laf quu, nto xomotuov ut qinar zigemYqjce(), upn es nigos ev ergdahca ip u razum lxghi, ygodg, iq makquidaj aossiot, uv e zpvo hdoq fumfohnr zi gti YukudWkkfa gsitopuf.
Fkav ah sik eh baojm pore.
Omt xuf, pia vob’t, ory sxouyxs’d, zeu osl neykewoptu pu hvov juo xac ax ski qudfuat hobgaay vfe Zimoy.
Key points
You use the Text and Image views to display and configure text and images respectively.
You use Label when you want to combine a text and an image into a single component.
You use modifiers to change the appearance of your views. Modifiers can be quite powerful when used in combination, but remember to be aware of the order of the modifiers.
Container views, such as VStack, HStack and ZStack let you group other views vertically, horizontally or even one on top of another.
Where to go from here?
SwiftUI is still fairly new and evolving as a technology. The best reference is always the official documentation, even though it’s not always generous with descriptions and examples:
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.