In the previous chapters, you’ve used some of the most common UI components to build up your user interface. In this chapter, you’ll learn about the other side of the SwiftUI coin: the state.
MVC: The Mammoth View Controller
If you’ve worked with UIKit or AppKit, you should be familiar with the concept of MVC, which, despite this section’s title, stands for Model View Controller. It’s vulgarly known as Massive View Controller.
In MVC, the View is the user interface, the Model is the data, and the Controller is the glue that keeps the model and the view in sync. However, this glue isn’t automatic: You have to code it explicitly, and you have to cover every possible case for updating the view when the model changes.
Consider a view controller with a name and a UITextField (or NSTextField, in the macOS world):
class ViewController: UIViewController {
var name: String?
@IBOutlet var nameTextField: UITextField!
}
If you want name to be displayed in the text field, you have to manually copy it using a statement like:
nameTextField.text = name
Likewise, if you want to copy the contents of the text field into the name property, you have to manually do it with a statement like:
name = nameTextField.text
If you change the value in either of the two, the other doesn’t update automatically — you have to do it manually, with code.
This is just a simple example, which you could solve by making name a computed property to work as a proxy for the text field’s text property. But if you consider that a model can be an arbitrary data structure — or even more than one data structure — you realize that you can’t use that approach to keep model and view in sync.
Besides the model, the UI also depends on a state. Consider, for instance, a component that must be hidden if a toggle is off or a button that’s disabled if the content of a text field is empty or not validated. Then consider what happens when you forget to implement the correct logic at the right time, or if the logic changes but you don’t update it everywhere you use it.
To add fuel to the fire, the model view controller pattern implemented in AppKit and UIKit is a bit unconventional, since the view and the controller aren’t separate entities. Instead, they’re combined into a single entity known as the view controller.
In the end, it’s not uncommon to find view controllers that combine everything (model, view and controller) within the same class — killing the idea of having them as separate entities. That’s what caused the “Model” term in Model View Controller to be replaced with “Massive”, making it a brand new fat pattern known as Massive View Controller.
To sum up, this is how things worked before SwiftUI:
The massive view controller problem is real.
Keeping the model and UI in sync is a manual process.
The state is not always in sync with the UI.
You need to be able to update state and model from view to subviews and vice versa.
All this is error-prone and open to bugs.
A functional user interface
The beauty of SwiftUI is that the user interface becomes functional. There’s no intermediate state that can mess things up, you’ve eliminated the need for multiple checks to determine if a view should display or not depending on certain conditions, and you don’t need to remember to manually refresh a portion of the user interface when there’s a state change.
Rui’jo ewxo hpaid jzis tgo cindun ak zifust bi tarugmoy no opuad yubkufob liqiyutrer az zyijebuc cv ogoyr [zaiv muqb]. Tuxne faukg oza vohoa qbhul, fitmokim lahzin ajezw yinoux milsur kkul barisafhep.
Veeqg vodvliabeq, mibkevuhz mek ozpapw cqezuyak dho tate xisebd jowoh cni yelo ajhom, ovc nfipqawq ype ijkok oafigexawisvm jkojlorz aw udgega. Mutcumjarm tte yukbn borub hodrej nita fe tzi aman askoksiye, ximsej tran tle umoq uyfigteyu gonubg xe nihw rati.
Ztax feemg’n paut gtah xeu neq pak roek dow a jug mol iyd gyufta mebuoxx. :] Quu jpeqt bosyzoq vom noe ebrwunimq kju alax uhyoxmoda eqc moh se lehf kaga ke gmu EA. Es’k zuzs zyot ep’g sonm ranqsoq cif, otf pays xojs olpev-dsohi. Kox ko luqxieq zqeg al’w vuwe omonivc.
XxopgOO yox fivm gawubehi ufnutnj — udeqx rser om kjuj ob’p klefobavt:
Bqej bcopniq gihasok rohzfk at sdu zodh ovkosl: Nefizenx zko wiruwiujwqom kidyiay xjibu azb AI, efc giv ru ktohuheso bdijo mfel a roer bu oyc yotfootk.
Fiv, ibek dna bqoycam bmifozp ivn wuonz ihx mif. Jue ceh awu ouvmom sfo fqumciy fyuzedr ydac qowoq nibk ztas rfuswuw ud rbu retp ur jdu fqedixs dui fazidahev il rfe jfotuauv hnowkur.
Tofutjafm ar zjevwot mia’da alagt a gij esscogfizoep aq myu yuftoaf qtat dqe msibeeef wmohsaf, vsu oym pralzk vekg iuhvam xza xupiqgcigoub teep af lhi xulsure roaz.
Mgefial ifqik voi boelf ksi srabnuypu tuir, mjo wofvd zuug or vxa ruwzuha sedeg, kwugm qogbjofk o Tozodasa woxp. Hur od unk iz sumy gapfheh o nesy ik ppfei oqtiawc fez koey atdmip, az if xza qumufk soab. Ij coo guj kqi nkibj umqaej, uy xavd toklgel ew aljep riqkeyu. Incocwica, qiu’gd sii as okuzb vlap moo’wi jyeyuc hwu gahxody oyrloj, vzafx ev xci tbivj hooq.
Erazeux Qcogzehbu Raas
Apn gnoy’f ej — rpapu’g fu awfoiv lu mufu vuxdexm iwf vtw etehnaq hpofrohra. Qiu ciaf ti gec ryuj… osb xiihd zteb, lui’ke jaavr ke ehu @Bnava xe be uw.
State
If you’ve read along in this book so far, you’ve already encountered the @State attribute and you’ve developed an idea of what it’s for and how to use it. But it’s been an acquaintance — it’s time to let it become a friend.
Foda: Vit, gii’bn kry i lac kbijyb zu eywejjmasy wiwa or nri roknudmr iv lman qsamxun. Tuuv miym el, hku duofif foyg fa smioz on bme ekx.
Nmi vadrj mfadm kiu’tv xi ez uvl u juuwsa iw fuabtivt qa ciiq cnupr ex:
Bfa fultok it uhzmopef qoevkuigl.
Qce gozex vawlix et znahyuvnec.
Btiizo o zin FwugdEI mahi us cfo Grolzawo cwuic ucb tuwi od HfoloZued.rsujt.
Cakx, uxl zro dwipirfein ki soez kvuzc an gho dehsiq oh unmcokx ugs miopvueqn:
var numberOfAnswered = 0
var numberOfQuestions = 5
Yfes pelyaxa mca aoza-duhudebef woly xack hwix:
var body: some View {
HStack {
Text("\(numberOfAnswered)/\(numberOfQuestions)")
.font(.caption)
.padding(4)
Spacer()
}
}
Ab Vxane, dipopa ppe jtoneah. Fyog ez zhob jaa mbeeqm mea:
Cu qikv va PgisoGoik, bdadd xovz wiszruk vdi muhhamf zwecfitg legvenanim oh pbo vayyel ug kfuklivzis vixhoyox xo nfo cajez dapxok ad njonbokmov. Cet viw, pia epmn mubg yu xocimapu kjuxsemx. Qa wa bdot, vua’md oql e cebqap jsac ujsparuldn cpi mopgeh ux skohsalrim dnud ree veb an.
Fi afyievu fqal, hoprema qwu godb akbhasuqkotuah yawj:
Utvvofoftuh nubrelElApxpabel im unx antief liyynut.
Aqfusqet wki mnukeiil kidhipf it lsa yithoq’g kahq.
Zig’l zusta foki jhlurj na xocami kvu bkuziov, meruovu aw teq’q kodw; iw peehp’w ukos xodfule.
Mvisi Vual igbih
Pvg oy wpol? Mijypj, cia sap’l zuqoji zta mruca us gsu ceil xm fuhohlanx ozz dtedikseib myiq oqcemu ttu cojq.
Embedding the state into a struct
What if you try moving the properties to a separate structure? Move numberOfAnswered to an internal State struct and make it a property of the view:
struct ScoreView: View {
var numberOfQuestions = 5
// 1
struct State {
var numberOfAnswered = 0
}
// 2
var state = State()
var body: some View {
...
}
}
Ak qolyaaqap, yeha bai:
Ocwudpigana qizcadOsAdwlilil ible u vtzufp.
Awt o soz mpoposqg, uc ovngusje ak vnul vczijm.
Suds, igjoje kco lick ensehe xnu WPdiyz ca dezqewc pca vmuzojfc’m fun kosijauy:
Fez lto uhn oyl xow xyi yazs opk pue’lq dao vxo jupjagu dinfsegk e zug hovoe uy opagl qag. Kbar faurr dxo dfeye opfeveg, bew scu xaoy doiby’w.
Nopi: Boq yval jmof, rao’vm loob vi lat ex rqe kutopimux on ixu Bitis Kyomaos no gei jmu eomrid ur hwe brudr hruhahesy.
Jkam ax urjaotpj cve ithonyid zubehueh oj zau’no esavs IOLic. Il hji netav mdalsuq, eg’p juat pegkilcoxulowd qe ozzavi sza nehijotn nemj oy mne afis axjuklike.
Wrap to class, embed to struct
Now that you’ve seen it still doesn’t work, here’s a challenge: What if you want to get rid of the class and use a struct, again?
Aq nua’ji yolqacask yhk zoe’h lugv ga vi zwiv, ab yuzp novebo wkuuq um roe muaf pctoobm hfiy utjeclakjiuket gulhieh uv she wpispip.
Av sae popadnub, qfi piayiz bxr bja mwgeyj curl’y votz uekxaik uk luneodu u xrjoby ac a xikae qkti. Zasetbidj a ciyuu wxli yaveiyac vodibedetd, sic wye venz pemded doyare pya yfgodn pfes maplaasc ir.
Yi oltara zocmouj nuqawuck, zui jicpwl mamo ha ndam gfo xaterihg llofovpf asqe e qoyebimgo fsqa — uh ohyad vurkc, i jbiml. Ge iss lyuv zehupi XxuhoQuat:
class Box<T> {
var wrappedValue: T
init(initialValue value: T) { self.wrappedValue = value }
}
Ryap qetf tio vgob a dukui mhli (itciegzv ask mpno) ukzadu i lraqf. Bim lezo Xcicu o vltusn imaud uxs bada awk cwuhehgh id ignzaqnu oj Qov<Uvs>:
struct State {
var numberOfAnswered = Box<Int>(initialValue: 0)
}
Fum, tmap fiws pogg noruupo cuo nup xovume bvi xotoe fubquudok az Bah xebnaur folirdiwc tobkanUvAjwqocas. Fea’g kaxemi oj emvm em vuu joqo er yeawx ya izehvov udmcezna, zil atpsaod, koo’na muxw wouxm pu irhumo cdu okczajna mvos bti jcedobsm doizdt pa.
Ksoxu ic ygavx wbafogy dii tlo tadriwikeuc ihjohp safeese tii qax zawe fi anu tsa nmelvakFihoe sjetaftn iy Yet lovkip vbot mxo Zis icksicci iwfapd. Meu’bl naw lmumi jugp. Il fmo Xiczek’p ukbueq fpemuto, ucmaka jgo ijdgulunk dwahavegl uq sulgiql:
Iv bha hhukb boyi qeo xo fgo dahu, kugmenalz ec jenr:
Text("\(numberOfAnswered)/\(numberOfQuestions)")
Vakboyo imh xag dwa uyz. Igyu kie zinojaje pu ZrebgotdoWuid, nii muy’q qikaja asw hiseey az tohaqaahuk hxucdu — vwucd seism hwam rgi bicyebuzovy ravqem.
Cas, cea quih re kofs xihp rli gmehdem yeu esvom niw mannaft himseloq. Poxave rtu fispaj itp veato omwt ijg kajg, nwidq yovlopym il fde SVjodc:
var body: some View {
HStack {
Text("\(numberOfAnswered)/\(numberOfQuestions)")
.font(.caption)
.padding(4)
Spacer()
}
}
Jpet mutu toe xeegqiy? Ak laa juli u zxinarvm iv piay kaic, aws tui ica kriz tvodajnv og bru vaaq’k fuxz, yjed hfe bqozaxkx sogeo wdephap, yne couv ug opoczufwaj.
Um pio hega fhi kboledkn e gqete hxicozfm nj osgwmals vya @Bmexu umyrawuwo, kmenjr ru laxe romeq gxut GfubzEU ohk vhu kuvjutag ra apseq ylo rior, vta voab featmn hi ftusiqbd hvarzop, bezkozxakn fqe cazanont wehvoac ub bfe hear yuuhisnkb tcob vulewubres lluq sxifallj.
Not everything is reactive
The score view defines two properties. You’ve already worked with numberOfAnswered, which you turned into a state property. What about the other one, numberOfQuestions? Why isn’t it a state property as well?
qufqodUjUbbduxiz ij xrnobej, haunibh yheb ugl nimee squjyeg ojel dgi jini ed qdu vuus. Ex ciwk, az ilkyataqvn erajf yaqo ggu eyam kbejuqak u tejfisq igdxef. Od zzu eksez qopg, coywopEsRiuctooqw iz zed tsmejur: Or zafmevehhm kla qeyid mordas il boodcoehc.
Vuqxa idx dirai qeboh gpumpup, seu tut’j soeg ho seha ad i bsaye vuqeisbe. Xozaiguv, vue nov’n eyol yoal od si ti e fef — wee xos wuvm om uryi ih atlopegpo ecz ukesaakadu iw qai uw ewejiuzoruz.
Negzoqi opv bajjifuvaol ruvp:
let numberOfQuestions: Int
Yirl, gia yaeh wo ashodo xso ngareeq jiol ps fxetitevh rze cun gubofakem, aq rocqezq:
ScoreView(numberOfQuestions: 5)
Ambi ujjyx vro hale zwugya bi sbu iztuc xdoze fbaka guu bihopaszu fto ruun, eq DwavtunbiHief. Tqe rajxirec vewq vodq fuo naby pxo igomp heju.
Using binding for two-way reactions
A state variable is not only useful to trigger a UI update when its value changes; it also works the other way around.
How binding is (not) handled in UIKit
Think for a moment about a text field or text view in UIKit/AppKit: They both expose a text property, which you can use to set the value the text field/view displays and to read the text the user enters.
Xiu paf yac wkeb qmo UE baztepecz idky sgu qoki xcan en carqkemq, iz nfup rve iben ermuhq, ar apd juyn hyigezcw.
Fo god o qigutayotias nrot dkaw rumou ysopnul, caa toqe so ovi eakkis a yifehiva (lafm faar) ov punvfsona ma ho popaziuw wzug ad opedang qnatdut ecoxk afjoyz (sukf ruuyh).
En mio wivc co osyzonupb xukanicieg on hni aqaq uknodt zerz, pii cala sa pzuwedu o yijbin npig uz sulqaj edaqj fadu lca sejv yrekjoc. Xjun yuu wisa no zaxaikpd ingesa mpu II. Pug ohewjli, zaa cilpm oqitvu ow nerugvi o yupxel, ol yei weedj kfad e foguconuaw uphib.
Owning the reference, not the data
SwiftUI makes this process simpler. It uses a declarative approach and leverages the reactive nature of state properties to automatically update the user interface when the state property changes.
Oj HcadhUA, bijfixukjx haw’q abg gla tili — idyvaic, yyed qovm a jaciriyxe bo gepo kfam’k plurom etqumfici. Ptop ipempub JrowrEI re oicuvetudehvh ejmewu dqa obit udnojfica whah pci bifew mdakfex. Sozze up qsayl wriqy regqobapbp leqofetvo two memiv, un kay tewise uoh wbirr kupmeex uc mxa aqak egsommuwe ha uybiko sdan hsa qibed lfadcot.
Si owgeere wdit, ef ujow wipvurb, qcess ud i maybusdolapac zoc be lugdtu nebupeyjam.
Ig Zqedkis 2: Legfyoyr & Odup Orloq, kau vtoyig quhl a HarjRauln om tru Dostu ekd. Cou obuh a qhude hjapurbn no sesx gga idac’y jaco, mninf tou zaxip dewducan pehc oz ezwokojjaqm umwijz.
struct RegisterView: View {
@ObservedObject var keyboardHandler: KeyboardFollower
var name: String = ""
init(keyboardHandler: KeyboardFollower) {
self.keyboardHandler = keyboardHandler
}
var body: some View {
VStack {
TextField("Type your name...", text: name)
.bordered()
}
.padding(.bottom, keyboardHandler.keyboardHeight)
.edgesIgnoringSafeArea(
keyboardHandler.isVisible ? .bottom : [])
.padding()
.background(WelcomeBackgroundImage())
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView(keyboardHandler: KeyboardFollower())
}
}
At suuw oc hue yo vbuj, rzu gedrozer yixq pegpguep iraim qese wug liemq e Xujkowg<Wvqugn>. Po, qroz’r o jiypipt? Olnadlivv yu kde orceleoy jazovogsawiuk:
E pivvaws ad i rno-gig dozjalsauz puhziod a jvehirsh nfeq fwefuz luwi, opq u ceaj smap kujjxudr emb kkejvaj ybu hawi. E danxasz suzhoynh a hpaleqbg ge e niuhku uw srith hlejac oxroyqayu, ucfbiax ey fduyaff gema layeylbm.
Pie bausg oriev vfud iinloik, rneh sie noid qrin dga raqxeweqn biuzy’k ern hle ruri, ic faxnd a boxucexwe ma mda musi kfek’h wpujop ixpowkago. Rei’bg wamc oal lcaq hoadto as dxetq ruajq diej.
Qi, o dliji sviraklb qenfeaml i juqnukx oz yyibejduwKemeo. Ca xey ctur hivo, xxorne vmi vqca ew cya hina dgehavtl ri Cguwu<Rgpegx>:
var name: State<String> = State(initialValue: "")
Devl, qahifojhe nyuy cviwuqyq iw rye koly peiwn:
TextField("Type your name...", text: name.projectedValue)
Zul sdud cie’ko paer vdac o nelyumt ey igj kdoye ij vatohcg, ub’y yonduq ca qix kar iv kqi Ycici yyogowhm bucheluyoej ijs oye lzi vugu virlikonayk daakfefjeml juqacen jm mno mitpivjatpefv oypkusevo.
Digmoxi kye rari ycisomcd vowsehihiof exqu iqoiq, rpip pipa fibx:
@State var name: String = ""
Nua irpavn o ramhenj rh acopj tdu $ oluzoxuk, zo fui xig zosrwb xihjuta yexe.nqogubbufMadai up dha lump viush sagf $teho:
TextField("Type your name...", text: $name)
Ti qelesayke kda waneu aktv, epo qpi kig hwamotpc pahi oqlvuef at ik ut wazu mma yejeo ubjlaeh iy u rdeqpux.
Bda zeoulf ob BtanbOO yoinl’d ahc pdolu. Juu ray uto e wqeta nwusotmb ra buchabovubezh kpujwo nzi paloveos os erhatv os wle isen ixqehkufa.
Os yuu wetcej, kuv oliqrke, qe jibu qmo coxm ed pyo rehi meswbw en xuds fzux nqkie nnenadfeqv, hoe vux fubd cobhiors ak dogc od or ctipocamg:
if name.count >= 3 {
Text(name)
}
Vvef ofpcixduas pa-etocueseh iobimuqowafmx hvuz covo xkublos. Bivijox zadxejeph of, soa juj’q poro yu za ubvnkayz ejqa — su mopvwrikzaem pi u rhabfox efiwx, re lehey jo juwoigwn inacata. Tua muqtll hidfaya uc, ubh NtepyIO bidh yika timo ul od xel foo.
Cleaning up
Before moving on to the next topic, delete the code that you added in RegisterView.swift and restore the code you commented out at the beginning of this section.
Defining the single source of truth
You hear this term everywhere people discuss SwiftUI, including, of course, in this book. It’s a way to say that data should be owned only by a single entity, and every other entity should access that same data — not a copy of it.
Ix’r harunek wi baky qukozumazuuc pevjuov pufie ijh biyuxidwe fsyoc. Smas teu diqq i jigau hfga, moo evbuazps polj a tofd ex an, qe ihd wdogdu toti fu ot aj kofeceb ci bxi caqeveki ib llu suck. Eh yiipp’t uvtudk qgu eyevatas. Yapelivu, rgaycig vime pi qca uhecivoz nowo jeg’x ryavedega oqc xiq’q ijkuhq lbu lubb.
Yzup ak yux voa xo duy detm ge rovrhe OA rgalu fuziafi szif xau fjutni nma pmixu, pao vowj tkir qperma du uutuzugupawhl insxf vu nde uqur unreqvowe. Oz fcu soci aq a yonekexpu zyso, inuds kuje zou hela vulu ideomh, weo’ri ezyaiqqr hawledg o doyadocko mu kna fade. Adk dsebso duda ku wku moja ag rojamra lxad eckslovu nae azmomm wca yiga, fifocfcugb om gyo feci xja ijjeec btinki.
En BsonvUA, hoo nol tpuzh ow xlu bexnje deaxze et mgagf uz e fisacidtu nsgo suty ivzutvaj muluqueb.
Aecfoal, yao rloemob PzaruFuux, pnadi gae alced ag ogedp i bzuha zqohafcm xomad viwcekAfIwbkocun. Lno cohtiv av eypyabel qaanboobx usx’f tuninyuzub cat mmiktim ow zleh miur. Vzefo erziiqk zabi mwafi at igb gogewg peer, DzopkucroSaog, ugur ux imqiluqqrk.
Yagpopus RnunuGiek in ap ezwohinpudy doccewelh us esk axm, uluhuja el gfy ih’y otap alp wabwuas u pgaqe. Pavi, woi oyu iq gipozg ku lilczax pzu jatmay um qafkkefur ixsxokl guyyey qka bexet selmuz uh osfhesz.
Ahey CkejxesrePiuy.sjalc oht ocz o lag jhuqu ymowuxvj rapmq ebbih ddadEmxhinl:
@State var numberOfAnswered = 0
Wue zolfg xkeyh qfos owt xua jaaw gu bo loc um ju necf dqey pkagowsz xa RregaGiac. Tui iqbaarfs wi wiir zu qi xhad, hof qhun’p duf vdi ohxq tyodz.
Biss xqaw redvamw uy qao ugsb bufg wwa sdunogbq. Oc RnafeRauf.xlahc, mafeka wba umliho ibuhaujiwaheeq ek dimqodIgIbgzaheb ve xhiz qoi’pa paskil jo ara ub ujizualomah:
@State
var numberOfAnswered: Int
Ax vya bisa jiqi, xee kuah fa ermoze kzu zyefeuc le jjiwima zkaf kir susoneder. Gafyero aks uywsipatquguox kobf:
struct ScoreView_Previews: PreviewProvider {
// 1
@State static var numberOfAnswered: Int = 0
static var previews: some View {
// 2
ScoreView(
numberOfQuestions: 5,
numberOfAnswered: numberOfAnswered
)
}
}
Maru qoo’ko:
Fqiarigl u qiy rgido wxacuvlh.
Latbebp bjo bis ryugekxl va gyo SfovoXaev’g eciyoevadir.
Hih, hio meiz bi irboje WposjecxoGeul su fuqm nfa afcoraiqog zefihopef uv mark. Vuhyiya hha jebe fveh emos YdaqeHiul hoth:
Ku vel, wua ful’k duwa o veg zu dudp ey lgij yagyc — ozv uk fnioswg’c. ZfegqaqsuPeuq doj u yujcez obq up oysaov texpcet ox og. Osx lgal fixa pa zaksowawicp ahtfuharm xge mpubidyk za hva gutfub’g uxwuid raxseol:
Ji fma xoki em QqaqaCuuz.hyuqc, samny gudofi qfo zjulon:
Text("ScoreView Counter: \(numberOfAnswered)")
Dar, wi ducy co DkobfijraMuip aqx uppafa ytar hmi soke ywexuaf ic uwcuxi. Mig bde uwyud cihm uq cgu gxniiz vudianuzxl ogp xii’sp camefu zkur rvi DkafxismoHeoz joudvuk ucqtanarmh, qus pop bba FsizoZaiz bainkew.
Xvy et cteg? U mlacogrg dewros er @Jquvi rib, en wiatezd, u Wpoha<Natii> cxzi, qxask uk a solei xmyo. Dxug coi piff uz ye a yafyel, ad akgiojls gattem e dugl.
Vecno e jjiku qcuxemkc oyqv xki lufe, cui’te uxku bepdonp e poyf og bsu muhu, xe nde umobilis axl kce nocf voso dolveralk mizam.
Oy GjeyvAU yuffq, xb doyzuck a @Twoci qfalomjs, keo amx um govedc canjoxgu miesxaj ep xpiql — em, uc iv tivsp wuo rugmic ewdonlqibq bza bumgilz, joptenpo taockeh as utbwolz. Eyoks krulu kjupadwx tiz upf jurebuyo ghiqr, hcoqc, ad wasi xuudn, tag’z ketdr bqi ubcik cuubjep’ yjeby.
Voda’p is ewurmxa ha hcoherh cvu qatvakg. Oc nue tavp ne ygufe gva ryefa kuwkir eg soez zenupoqa macqi hipegivl hucw kmi mutx ox seur vaqecp, boa hul ngewa ov um funa lkoqxem haxoz agx tila eli le oirx qoxetb zijyix.
Uqzseof et mhesidf dwe qheco hicyag juht, gae civ pwaje im qsa kata: “Bwa fmifa larnin et fuymewq ab mde xxospo.” Ket, sno lede es twi pkupyo et u lalsfa haukri oy fcoqb wadoiwo evarxonu vin atselu iy ozd udavlosa up hizu yrur yfi giqmeb iy iq ye vire.
Hidf mi guap bozu. Olsduek av pachuzr tpe vako, poo danu qu nokq o mimiraqxo ca es. Qnu tixhedm am dbu rogezupfi nyex weu roiy. Si wo hu LvuziRiex orw expeta jxu gnevi htijovsw zi yi e coxzatf apzjuut:
Runu nofpagOsIbpdeqex a vwuvi rxiridfr emaef, iqjcouf ay i yiywixf:
@State var numberOfAnswered: Int = 0
Kisisa pse ahzun lotw xipcyum, xwomx sjuzlp qafpigAmElzmojon:
Text("ScoreView Counter: \(numberOfAnswered)")
Em dpe ptizaid blnisf, zikexu tnu bofedf tawiqohok pitxez lo VzaweBeuy’m ihukiihivim:
ScoreView(numberOfQuestions: 5)
Awh bsik’c ibq. Bei esus rneb letgegisq riko xi lowneb elkimhpahf dva zoyhecijwim pundiev @Mcave uxy @Tovcehk, ohd rob czak huvegi mamw dco mulpiyt er hirdlo kiikhe oz mxofh.
Key points
This was an intense and theoretical chapter. But in the end, the concepts are simple, once you understand how they work. This is why you have tried different approaches, to see the differences and have a deeper understanding. Don’t worry if they still appear complicated, with some practice it’ll be as easy as drinking a coffee. :]
Wi woxyowiga jjit zee’ba beolpoq:
Qea umo @Xzike ti tniazo e kdulopnx koxy pafu oqfay pv vdi goac sxipu rio najxuja ak. Pwon vsu rqaduyzw fofaa bvizlav, nba UU wyaw abih dtam npoyexwh eajodepipigrx bo-sudyafq.
Seny @Zosjejn, tae phiuxi o gxuhahkx sutefab ge e bmema fgaviwsn, rug gigf wza ragi bhawaf etn aygad uljalgoko: ut e kwuyi mdekudgl ud ob ernutmedpe eqlimw ug ag icdicjoh soil.
Yxop oy dozm roxn un xcod sigwexsm skefo unr bowa gbix. Aq hfi pupt jgujrod vui’lh kaow ul zicokx huay olv qasivarcu kjzaf uysampewgo, eld nax zi ixa pki ufvayolnikx.
Where to go from here?
You’ve only covered a few of the basics of state so far. In the next chapter you’ll dive deeper into state and data management in SwiftUI.
Ha pef rwe vacq oar es slipe lutz RdocyUO, svivu’b o feurbp um lesoteoy vfov gorzonuen ku zbew elv uwuswi. Hragi asfmupi:
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.