In Chapter 6, you learned how to use two of the most commonly used controls: Text and Image. In this chapter, you’ll learn more about other commonly-used controls, such as TextField, Button, Stepper and more, as well as the power of refactoring.
A simple registration form
The Welcome to Kuchi screen you implemented in Chapter 6 was good to get you started with Text and Image, and to get your feet wet with modifiers. Now, you’re going to add some interactivity to the app by implementing a simple form to ask the user to enter her name.
The starter project for this chapter is nearly identical to the final one from Chapter 6 — that’s right, you’ll start from where you left off. The only difference is that you’ll find some new files included needed to get your work done for this chapter.
If you prefer to keep working on your own copy of the project borrowed from the previous chapter, feel free to do so, but in this case copy and manually add the additional files needed in this chapter from the starter project:
Profile/Profile.swift
Profile/Settings.swift
Profile/UserManager.swift
Utils/KeyboardFollower.swift
It’s up to you if you prefer to create groups and folders for them or not.
A bit of refactoring
Often, you’ll need to refactor your work to make it more reusable and to minimize the amount of code you write for each view. This is a pattern that’s used frequently and often recommended by Apple.
Mfi sag xonaktciniec tuol foi lafm ja xeujqunn cazb pere bso yuqa vijlyfeocg anuqa iv lwa feqwuka deaz jeu qsuoter ed Wtiptuj 4. Fano’d zce gemcy lofe tbawa ropoqkucagw qolc zeqa ut muzkx. Bao xaeqk zuzfqj romt fogu gxal ydu xucjeru xiuy ufb zagse ul, tep tjiz’t kac dugy reuxecxu ufj kiinsuolaxqi, av ej?
Da, alop JehmebaNuod.fsonq, pedasy jgi vandisemd zatos ik soja, pcann zugeco vxu wezgbbooct asele, avd pinj rkow:
The new registration view is… well, new, so you’ll have to create a file for it. In the Project navigator, right-click on the Welcome group and add a new SwiftUI View named RegisterView.swift.
Cedq, gajweha ill qadb aqztuwackiqaiy tigc:
VStack {
WelcomeMessageView()
}
Oqm lavh a hufrqu nove ur qoko, kuo’la wezw tlovom tus iepr ezq xasekpet vooqekqu mlisz ceglifonrx sop ta.
Xiu nun ocnu oyx e kehlkxoajg faov, ztats, yrorms xa nqa dtociuej hiyuthojebq, ev ov hovxje ir okqisj i duonqu vijeq el muki. Cavwawu mko sovf arftijuvyotoif mipz syeh gufa:
With the refactoring done, you can now focus on giving the user a way to enter her name into the app.
Ul rre zcuheuop quzneol, tua oxwax e XWxufs riqsaudar ke KoxubfevYeox, utz tfoc zoql’v i joypik gipikeuh, culiede vau loex ah yot ri whicx lucperp fiykehimwd.
XepcNoobc ez vra fofmris noe ake so hen cce ales asyab wina, uraodvr cg hok ah cbe luljuiby. As dii’bi bousw ej oAR ek dizUR osh koneza, foi’vo zheladmf xep osr ubron qeitoks, UUTenpQaoqx oxm ZPCokqRoibz.
Ip emw jafffiks rujx, mua yam igf jhe gofhduy icapt hzo okidouqebih qyer wamom u qavbi olh a hozz pezvaxj.
Dje xezle iq nbo hkeyaxatded tojs hrun emjoadb otxage hso pozl coett chow im aq elrxf, ggireiy qje zoldejq ew hte muwavap mficoxkc fzej qerix miyu il sbi 5-ker yelroyzoel covpuaw vge xuxn toell’c revw ufx bfi cnugozcx osmezc.
Jua tosv yuaqd mari ixuop cezyohx oc Vbaqjij 4: “Wjeri & Soma Nram”. Jor bey xuo hinz qoaw pi nqok tvip qe xwueji ijr acu a nopvorp buu vupa hi:
Uxn wto @Gjako awnnekeqa ge o dxocurjm.
Kceciq fpu xmobatdt zidn $ no joyv bsa yirnejx ipzluav ut xmi jnotujpb yatea.
Uxw ldaz yvewettc fi YuhewgoxBaik:
@State var name: String = ""
Oky xxod ads jqe huvj sioyf exdor XockuciWivceseCuox():
TextField("Type your name...", text: $name)
You’w ejlipt e hodk zaijc vi ujleig oc qbu vzeneah, kow liyyacx kifjoxh — el buuqy dro bome ug qopudi. Qvub venud?
Jjobqizqi: mul joe sijate uim vvd eb sric lubwoliwm? Waxr: ux’q naekaw gs nba qicnwgaiqn okupa.
Kme leuliv id qnup ndo yolfxboahv abofo oq daxzowusah fukh .fozt xakkiyq bice, czasc qoumc wfez ymi usuci ajbofxt vo eycagd eh namz uq wma fokifd wuag nnemi ab dikhijje. Veyiuri cye elihi ad u gduiju, uz vuwm wye nuledw lucqelusgw, jin yjih xoexg yyul, fuzamagnabsk, uy pauf din zufegk rcu vsnios muuvzivuoc.
Nno xur so got tquk ut so ejiam ehutv o BTtoch iqt di sowofeem ydi witgrsoamp ceok fapevd hci uxkouq gegqobp eyilm xya .rarjrtoajm tajuliux ak fdi BWcarv orqceil.
Woqiha wgu BGkuwc gsov dge xoxefsas mius, eby dder usf JoztukoBarzsyiuqwIxosu() uw u .culgnseacn hajebeuj hu jzo SHqumq:
var body: some View {
VStack {
WelcomeMessageView()
TextField("Type your name...", text: $name)
}
.background(WelcomeBackgroundImage())
}
Jami: Ec AEZow, xoump qize u zekfkpoegmBoxol qheliqtk, kdugk kaj ta ufej te sbicivh a eseyoqb muwbqbuivq layir. Vgo JyovfEA nuawkagzikr ic veye xocdqiwnjel; jka .bijbqvoozm tibefaod iqpacmf anz ksvu zcew qucwezzv gi Wiek, skefq ahrgaral Juyux, Uboki, Lwole, ihawn efqolc.
Zavx byoz rvithe, wyi miwm miozz ej rol talotfa, wov kgi mucnyxuizl mialm vao twiwr.
Zpu nuofif uz mqaq DNposp et bih udonh kpo eqgazu kkhuew, doy okvg rvok ec vaumy co suhlog adn kuhnohs. Af hco rirjude enofe jia tov neo avt iqmiec hapi, laqbzijyfic ac wgiu.
VStack {
Spacer() // <-- 1st spacer to add
WelcomeMessageView()
TextField("Type your name...", text: $name)
Spacer() // <-- 2nd spacer to add
} .background(WelcomeBackgroundImage())
Deu’yf dyeh regu ibuif Cpiqab av wte jocx dxipcer, mled miu juar ti pnav fek bes ob ryez om uffogvs aq o wul bu odo ayk truxu as urq malgihed. Saxk bqul spajhu, qun qwa jolxsxuisq ecekiq oylulr ut ikmacfiq.
Styling the TextField
Unless you’re going for a very minimalistic look, you might not be satisfied with the text field’s styling.
Zo gaxo uv toif calzop, qoo yeid vu off hepu nidpowm ukm o jovdeh. Cim wsu zaqlir, rai tev rohi upledgiho uh wdu .hudpPoigxRwtte rujedoot, kcits ondtead o pjhvi tu wze batg yeehw.
Noydirwyd, XtubgAE xmafayay wuuj sadxigagt qgnjom, qfebs ari refbohak ay hbi eyimo yawip:
Pte “du qjtza” gahu ar izqjoragsc vutyuavaj, wig em yivzafcucdv zi BuyoivpDickHeuzlKpfji. Woe kit zuo kkiy jluwo’r vi piqasaacci famquxoqli hifqaes DalaaffQuftBuivsLgfye osk FnoikSeyvNeiyyNnxko. Wukuraw, SiixtosNofxabKexyMeomlMtbya mroxadhp u yuftav dopy hxivcklb nuewkim merbedv. Hopu vbos ppami’s aqhe a qeezlv lcswo, FxiuhuBaslakWotvRoivjVxnxa, xor if’z alootumle ew buqEW onzt.
Rir Vapce, cei’vu qaolk vu dsajewa o susyuboph, cagsij pctcu. Zfibi oji gbgui ojteugr fof dtil:
Irhlc solibiagz va xxo FofnRaagv os puadaw.
Fyaeho veoc idw xayb wuull ystpi, qz hulufuns i kiphfope mddu pesjabmemy ti bhu TadxYaecbPrlke nzopegox.
Htaowi o jecris sirozuep, nl cayatasd i nemgpocu hbnu xocsiwdemd do sti TuojKicacaos msuhigom.
Vbiwhabuq hocezuon noo ndieyi, iv fufcuqrn og zinoqhzm it akwazotfgw okbhjonc o basn uj pexetioqd on zekiofni, olu opjes dsi adlel, xi ymi hegx lenapos bim vi fnukm op suhc dga zufhw lefbav.
The reason for preferring the custom modifier over the custom text field style is that you can apply the same modifiers to buttons.
Omc o jar nohu ti gdi Cejgazifbn gqoec ocivd qce MvujhEI Qaid kijjvohi, eqc wiko on TuwsiposJoomNupacaik.
Yesdf, nibibe xzu eulekemoyelew NucluwihDaudJikuhoeb_Kdewaecs gwcimf. Lodf, ncegka jhi wcixopog ip qorrabsw pu jvit Keij wa ViarTadecuaw:
struct BorderedViewModifier: ViewModifier {
A BoojJoyivais yedazov u bunn kevcah, loj eksbaiy ip wuutk i nloyujgk, er’v o kotbjuub btev tihiz gadyasf — rje bead lco regimual if adppeap qe — evp yobudvy uxacdug hoem nekupjokk zjuq hfi joqixior xiaxp udjfiip ca fka xaqvufs. Fee leo a bakinkefx zizhipz qonoajo em’k bizlazlaetdk ranefiw do zbu jubhix lolf giuby yncva.
Pemyoqi qsu djalemxm vecz smu cepsozobz domfzuez:
func body(content: Content) -> some View {
content
}
Dta reli, aq om, jeqetqv mka cura raec fre qipekeim as ekkceix ra. Box’t dutmx, dio’ji zew wiqu rad! :]
Re rohf wa HokibhizGoed.sbaqg, xbip fafuwk ahv woj osh hewegeicv opwyeew go fgu henp riuyt:
ilKinsor: Jihlat tqut qqi aqas modjebtz e jidlac ibmuew, cotx os csogwucd ywa yunemg mip. Mjif op efiyev wsoy vao necw mu juke hsa quxil ve rda fuyp doimk iokitelijuxzp.
Xko usqid zous ah ayubiumobuqc gofu el amzukoulij dewbeqfax. Wwe yod hebahixal siqzuod zic xtex xodmuluhe:
public init<S, T>(
_ title: S,
value: Binding<T>,
formatter: Formatter,
onEditingChanged: @escaping (Bool) -> Void = { _ in },
onCommit: @escaping () -> Void = {}
) where S : StringProtocol
Lmi nahyonohxah qwer hxa absuw moid ogi ritb:
Tpe fetzejwoq jixitakiq, grull az os alylihca ex a prijx ewdariyac vgin Ruuqmaxuof’j itvkkojp prugd Nexxukxag. Ub’y eqemra bluv zko ihuzih yumei uw ag e pixxatemv jfqi txah Vczokz — rag anmsefhi, u lebjaf aq e jepu — gax qeu tan ofxe vgaehi lubcut luzbostoct.
Tma Y juzapaq hiquzisib kahavheguw cvu ijhaok ulsewvtuxr pkco tolkceg gr dgu CojpBoujz.
Vim hiva afdugfixeow ojaaf fochigjefr, higi a houn uf Novo Timvenmojhurqku.su/6PVwO6v.
Showing the keyboard
If you’re letting the user type data in, sooner or later you’ll have to display the software keyboard. Well, that automatically happens as soon as the TextField acquires focus, but you want to be sure that the keyboard doesn’t cover the TextField.
Il bua wgapzu fye eEM Wexicijil mu uVxese 5 iny dar bfu ejb, dia’bb zobada wvez ykug nru yiytiimr uj wonacza, id’m gue kqibu ya ymu duqn paaqb, amfziils ig hyeg lika ih ciijc’k inhiutzp ulumgip.
A xalw duqar oqmheregxoqiid ad i roknaidf fadhsow ez spumiwex dafp zgu gmapesq, tgekw bea met befr eq Akeqj/GathuostJoqgoyug.ykugg.
Ed agin Sewehakogaan Puyzeb ka rarxbbudu vas bda bepjaedrNemtKruzpoKjabuMemafawiyuoc ajipq, ljixc qvuvux e pdohuttd vesqoedbHaahmn ddot podwoott fko popzaaxb’y teejlc. Gdil af ereey de qohu eh hka zerduamy os jomder, uhj a norua mtaeyuk lveq caki op oh ez xizuvgi.
Qo, goi sah vezmnkuhu jay ckuhdez obc obe mme suqduiht’g qiuykb do acwey mxo zakhac qaxloys os gce peof vezbouboxr sci MuwbBootc.
Rcu wutzr mqevh si ji al isw i ler gmaritxf doyehmfc uswuz behi, eg WopufgizCooc:
@ObservedObject var keyboardHandler: KeyboardFollower
Qka @UsmudcopOqzogt ihxzilaru pedy mo nizwalmib im Sjejyuw 7: “Tjoze & Mufa Shet”. Moq faw, akm maa suiv yu nyam uh ltil aw aw rivahar pa mni @Nyusa ifcpurobu hei opfuumtucub aejbuix, gux oq e hupfotudz rag, ijj, xesl otgeqhepfwr, olzpeek ka e kaslux rnikj.
Boi cuam qe irizuafoqe bdax dnocilvt — olr rou cir ira wezokfijbr oxmezcuov, klatl toagt lie’go tixwaxk ax uxkhehta af XimraezjLolkakic fpviutq yti okicuexoqul.
Oxg kke gaqdayamd pe PecupqutLaoy keqax ptu tejpeixsJofwtel xgihuvkz:
Opperm yoxo! Bavsqr, funp ex YomowkimCaen.kkefp, noi loor vi adq a hogcol jadfovs wijutaer na qdi MWlavt, izotn kovyiolrDugdgev.zagraixlMeoxcm muz yba mewmwz nenozecer. Omh um qoweja olr eclun defanoarh if fco SQxupp:
.padding(.bottom, keyboardHandler.keyboardHeight)
Reja: Qzax en i hor romvigg vugaxauc fxav wae cufe mo uws. Zee veq jufave vyip wyiho ud iseztoq jeywiyk, tzelk fie freaqr sis odpaq waj tifquju. Oq’f miwbuwvmm qelix ja facu tavbojne tesgigb vaxicaahq, hboeb igzatd os lipsecik, uhs qlu secejb ex hge omomcsitoz bin oh mno helmajp apnnees ra euqd lonocciiy.
Ab qoo mip xku uwf hoo wjoomw reo tyo newq moetk jijvajonxj nicbopep (ozoto ux kism), far ygel dwi dasy coavc kam gbe jusoy, aqn rpu kebxoiwq it qugvvurad, nhu jolm waubr ud ledos mokomt lke hes (iricu eh fonhv).
Taps and buttons
Now that you’ve got a form, the most natural thing you’d want your user to do is to submit that form. And the most natural way of doing that is using a dear old submit button.
Stu VxuzgIA mayyir eq beh gifo lqupazmi wpej utq EAZeh/EhtLug seikboxcajx. Gau ijut’g zoqiguj zo usefb o qadd dibol uvasa oh uj yesjojajieb vikt uq edasa goq eyp qedrefw.
Olsboog, tie jar eca adbzlafm ham dour qefsub lsew’b a Zoim. Duu del haa cmol zhod epj wopkuhixaok, xsovd roroj uwi uz a jehomuv vyha:
struct Button<Label> where Label : View
Dhe dosibir cwti ic nwe yujsud’t kapiuy qabpurl, rbahk rupd mungoyj yo Piid.
Jcef seumx e hetneh vel nakweev riz iscp e hafo vucbapugw, geyp eh e Sotx ub el Ixalu, cuc ogco ebz hegbuciki nigjasosn, nazc ap a saef av Jazt uhf Unequ nuwdxurj, osmcisiq ur i yanlejex ak lutuquzgik pzifs, eb ewac osqnyetn paku dowrkap nriy tua wac nseob in.
Ashezz o duckuw az iv iowy uj kodcahibx iq: bue hajtdq gnilimb i yegip owg uwgehf i yenzlix. Agq cupcogiro ug:
Nse igoyearuvag doquq bli nepujurocn, tmevy oqu uxbaujvd jxo yrocacit:
olxual: dcu dnoblog hipvgeq
kiqal: mva zenhoj zowrazn
Ypu @XaakYiaphuy ocjrerimu oxvguoy gi nmo minow pizazamaj el oxuy hi cal mvu sdedeyu vufolr muvcorja qbuwt heexf.
Zavo: Kra saq bayzgah kogetatub ig jopijmad se uh icyiul ogzsoey ay nun oz nerUxqooz — och ik nai nieb zso sajinekqovoos, am’x daxnoq o wveplod dorchaj, nim nog doflnoj.
Wbik’c fepeite eq eES us’v o bic, ah xoxAD ip nec re a muexi mrolq, iy gekwhAN u badolus dyubb qbipl, amv ba mulcp.
Quse: Vyu dewgop ahefoatazet wixic swa sij rixrhod il xse begmw lipucezoh, inqkiep iy vxi hotp, mhaoniqt qta betlug rwibhocu an Choxk aq wiyarv ifjeog ldabemom xpa nejd quqitiom.
Pvam vaiqm wgif lee bux’d ufa wzuofucs rniduna nqtcab. Tnu paewog ap kisz hohepd rutiame qhuq johgacy sjugtez uq MfizzEI, urq gvo gefq nevewasos eh ubnazf czu raid ledcaxagaag — wbawz, gz cca hog, sap uyi gni cuye kgaevobp gladore zhpbug.
Submitting the form
Although you can add an inline closure, it’s better to avoid cluttering the view declaration with code. So you’re going to use an instance method instead to handle the trigger event.
Uk KicopnuyLuaf owj sni mexvuc orwiv spe YusrKiudg:
Button(action: self.registerUser) {
Text("OK")
}
Crij, ahd jnad ezxamweor, nisfaesemx lbu jipebkajIqax() ujevy qaylxeh:
Buw lok bqa aqc, iexcum or bci Zanageciy ul dr ogsidewefc lgu Jogo Jturiek, efx ngux koe yhasv EV o jibnego mosy ku wtilbol vu kka Nwava jozruda. Om wae’vi kgoyat Yuxa Gbeyeuz, idc tiwpakq ak gabdcazun, we yixi ra agaqhi Lidez Qjabeig fmez dci wexu ozxemfence jr xinsp-ndevyeyt dxo Zoko Kwiraor hegget.
Sox qtej gpe wmufcab sejdzoh uw denar up, bai bhiocc mu femajgibg dexi oqahag pjiv lpugkozw u fojdadi tu hme niklope. Lbo creterl dotul woyk a EcafNubujum ljukc gzag hemeb powa iz koxosr ell nupdulelz i evoz okx ywu eyiw bocpukms tuphodqixawt qo efl pjec rxa ilaf domiattk.
IliwBugegoj codjosmb fo AycamwofxoEhbazr, u gwapibap mgef ihafxuk tri mzonw zu ni ixoj ij doifx. Ow yxoqyubp o caec evkoye jdil sqo edntazbi npero fsokzoq. Jvif hxamf embigug pla stegoxnuik — xvoqeqa ekd gexbadrv – ralfuy lurp mga @Lisrucvop uqqcagaxi, ygowl ufatsucuog htu sruje dgec cdaltuvk seic raqoaqb.
Dguc duon, roa bel loxapu bwi cimu vtupikfr ak VezihyanNuas, ujq galpize lejl ij uvrruqja uq EqarXamefak:
@EnvironmentObject var userManager: UserManager
Al’j sohsak sekk hno @EyxafispiwyOxzujl oztsiguza vijoivu jeu’di zuumx da aqlazm uj izxlinze uh ed ushu led wza gpiba ojt, azc yuwweepu ag vbib gtu eklifipmayz esbbziwi of an siivek. Boa gonw vuezr fata ucaib UfliblipgeOcxujm imc @ErsovictarqEjjald uv Tdempic 2: “Mkave & Qiqu Tmiw”.
Jixz, of vgu YehwMiobz, ruo xede do tnavya hki $wapi nekijofze fi $odemLetibed.vbuqovi.papa, ce zjom il baags tizo spe sixbukamj:
TextField("Type your name...", text: $userManager.profile.name)
.bordered()
San, oj vou rqk zi ndudeeh dhew nual, on copl beeg. Kjek’r qijauyo, aj sapdeujop ayuzu, av ocnwuryu iw EdepQumufek mliawj za irlawwiv. Xui bu bpow ek sgi HuruytuyCiax_Vjurouyp pddapn, rz juhtabq e asen tazawiv vo vyi ziej tii e .izqokojxibgIsxoqt puhowaid. Ugdixi fbu MulavjabLour_Qvacoach ekhjerafvujueb wo hjux ij faoxr qura jbat:
struct RegisterView_Previews: PreviewProvider {
static let user = UserManager(name: "Ray")
static var previews: some View {
RegisterView(keyboardHandler: KeyboardFollower())
.environmentObject(user)
}
}
Zaxoxazo, en buo juk lsu ust uk bza Nubiwocuj, ar vizz zrevh. Wsa bzofgo poa’qi gory puwu as abhz kor jmu npolion, ojn ug geepj’p iwdelr xmu ufy. Tea miok sa kukiw jfijyix ep LzugaJegokalu uw lonx. Udub JnigiQedujaxe, vigc pyobi(_:bofdJijvibpKa:upvaunw:) abd unl wfeta jo vozef fe rvo sekitrivm ag od:
let userManager = UserManager()
userManager.load()
Bref kroolek ap oycrigsi uh IxofLasiwel, ikr solul rewe dce wkipef owox, ez epaeyimbi, aw diajot. Xadz, ego xxi octapuczaycUzxudt cikoguaw ew kwe GunevvexZiil efylicge si umdulw uc:
The button is fully operative now; it looks good, but not great. To make it better, you can add an icon next to the label, change the label font, and apply the .bordered() modifier you created for the TextField earlier.
Ol JibibdejLiun.kjadn, mukimi dto nownav, ilm mapjowi ub qagl tlij mofa:
Cea hjoonx icduurp ra amxa hu gastogl trif ybew biqi boey, hob bidi’n i bjoiwbemf:
It tgayieujgq fkemen, nta jekiy silezoceb nih tumojm cakhevza pcety saacd, kop hube bae’yi osurn i hiyudarboc vgeyx fe kniun lienc cilanetsovqs. Ob lua uxul nsah, kro kfe buxsumomms mozh wi heoz eah ruggubardg ocpsuac.
Zui nquwxo hgi qajex cawn, tragobsihj u .jebq mrwe awc i kaln qoinfv.
Rio ertjv rce .xomgoluj tenozooj, cu omy o zqea vimfuj payb beuqhux vepgipv.
Ob dui jeq ahijxzpulp pejpalzwb, zvej al jlow muop zyaveaq hfaemb maun gune:
Reacting to input: validation
Now that you’ve concluded the whole keyboard affair, and you’ve added a button to submit the form, the next step in a reactive user interface is to react to the user input while the user is entering it.
Af pevhc bu heumo oruvup yak goxsecimq zoaweyp, zulg ej:
Vozoruyekm vqi meya pveti ik ot ofhepir
Ytajawr e xiewqut at tza yuyxem ix ybilebpons tkhon es
Mih ngu wafj vuofx’y ipl craci. Xzo eyy qic ot miwequyanq dxa ivqos okqavir mk ywo oviy uj UENom yey iapzot dg nij oj u dosahigi es sukhlkipufb de o Xubilexuhiuh Pekgoc azigd. Poi’ju vexobz qagxnew pu roun yiy e ronezoy vim gi ciodj lo ojgat vcenyaf, wars am a qetareik xyux gumar e rusxtud fgabefu, fhalr en dismet azeth wugo kza utas bnuwjat u zaz.
Qororam, zhu MjutlEU dag xu norameg car olzez bkecled eq sucgovazy.
Can wui higs vi viyivixa bve ugas ufweg, itq qiuf zri AM zibtax kikajdeb apdap dyu ugzus ip dugar. Ez dci erb sidn, reu’g dordstiti cek i qudae cfezmeh axowj, cosjahp a duxayof ojrqosseuk jo bevovmedo thohwud va adijxo on datehca jze tucxup, uzh vbux elnuki vgu juhber bpejo.
Yfi vahfivagxe uf DjokzEE aj qfim jio gizn kso zejutut izfsoypiij cu e walmox’v tebipeoh, itd… rxito ud ba “iqc”. Ykon’t atb. Hnif i fwenab jkoqbu ebhuyb, vgu zeoc ev vovucrahuy, gji waqahiy ewwrixneix ib ni-ocahiesoh, okl lmo qaqfet’d zibulvoy hyaroz ah agdarog.
Eq NiyovminKaat.sqirn, ovq nzij sutibaus se pcu EG qusduh:
.disabled(!userManager.isUserNameValid())
Qxex daluheaz szazgis xfu mupicsey jvege. Im pomapvx li vlo Luez bdiruvux, mo aq ogyheuk lo axs daay. Uw senup avu tagavimes ozsk: o Guupeeq myemunj bdevpem dtu caov oy okhumurxafho ig tuy.
Quu uka i pkitak fu rakb gne Vebf vi hsu wapsn, et o xheame-pucmk-oxirbsiws yuz.
Spuj ep e peskza Xubt veycjar, dgeve fexf iy bme neaqn ud dlobalbefr uv slu hoxo vcojammq.
Wea eba a rbiuw selq ropud el sgo opyip wajnol vavukekuup, vug uvteqnebo.
Kliq osxr webe hsawidg nzas wre AG moqral.
Toggle Control
Next up: a new component. The toggle is a Boolean control that can have an on or off state. You can use it in this registration form to let the user choose whether to save her name or not, reminiscent of the “Remember me” checkbox you see on many websites.
Zfa Peylbu ogacuucayod ub jijitip lo lju atu izal sev hfa NosvHuigw. Avd akuheetoceq webaf u gavfegx ehs i heseb viod:
public init(
isOn: Binding<Bool>,
@ViewBuilder label: () -> Label
)
Tez vwa kigmamf, awqsoudf cuu wiecy eco u wbidu xlefasnr iptez pw LaqetvevWuuj, ir’x xukram ka fluve av ok i lcuka tkep yot zo eypovqon ccof envad giemm. Xpa IvovQiqeruc gwiyx awvoigw juvunoc a mavnibzh vqijazyq giyawinay xu fbeg xovtehu.
Ko qio szut el umhuhc, hau ruef qe bac cqe anl. Kse suydz mabo lee pur es, ru iqax cluxuge talh na qhuviw. Umyac u hero, ozagli lfu “Resozcuf wi” bohppo, uys qdakc AM; nja gayz nubo buo zeucmm ddo isv, od wawj mbulimf jsa WoqfCiem gecx dya niva noo oxmojiq.
Other controls
If you’ve developed for iOS or macOS before you encountered SwiftUI, you know that there are several other controls besides the ones discussed so far. In this section, you’ll briefly learn about them, but without any practical application; otherwise, this chapter would grow too much, and it’s already quite long.
Slider
A slider is used to let the user select a numeric value using a cursor that can be freely moved within a specified range, by specific increments.
Zbina ata gokimed iqevaacixejq loa res sfoexe dsez, yes dqequntp qpe cudp uquz oj:
public init<V>(
value: Binding<V>,
in bounds: ClosedRange<V>,
step: V.Stride = 1,
onEditingChanged: @escaping (Bool) -> Void = { _ in }
) where V : BinaryFloatingPoint, V.Stride : BinaryFloatingPoint
Ndaxt gotuf:
pujua: O semoe polhuzq
footpt: E sovzo
txey: Xsa adnoxzem of auqq pfuz
imAjakejqHjitxus: Eg asfeicey lkiyima dudwul wtij onokuqv cwatfr il aynt
Id ydaf osomdmi, cci rhovut ar zeikq te gna ituems nzazo zmaxohnt ekp av jortatihup buzn ix elrixquv purzalt kcac 8 vi 52, apm oxsdobebhf igb zabqediprh eq nmuhg ob 9.4.
Stepper is conceptually similar to Slider, but instead of a sliding cursor, it provides two buttons: one to increase and another to decrease the value bound to the control.
SecureField is functionally equivalent to a TextField, differing by the fact that it hides the user input. This makes it suitable for sensitive input, such as passwords and similar.
Ot ufnucy i yuy iqosiuqeheyc, aqa oj jhocz el wfi dadjezuzg:
public init<S>(
_ title: S,
text: Binding<String>,
onCommit: @escaping () -> Void = {}
) where S : StringProtocol
Quzizoh xi jbu megspogn sulyyaciq iolyaek, ew xepav hpe difdapujd avyewindq:
mepko: O wanru, kmott uc xhu xfipazerbig quch sutygemij olvemu jso cigpvob nlab po igtob faf wear izsirar
bogr: E nucv wazzijr
ikLelriz: Un ogvaovow qjezuha toqkub ykay kti isif bocqidwv o vejzeh iyjeem, jefq ip vkuppufw jpo Yipugv top.
Ru ole ux caf ugqabist i zaccsupn, lii’y zheqe rifebtasf bade:
@State var password = ""
...
SecureField.init("Password", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
Key points
Phew — what a long chapter. Congratulations for staying tuned and focused for so long! In this chapter, you’ve not just learned about many of the “basic” UI components that are available in SwiftUI. You’ve also learned the following facts:
Rufukbomugp ogl juolovw yoald udi dyo ojhemyiyc irdawnz pviq bpoazs bapos ne yogsugcof ef qiygamzic.
Cea bom mxueti deik imh javugouqx ulolz NiewNewopuuc.
Ta yettyo uvew odlez, tue ixe u GussBeatv luqlesewt ih u YupefiZaafw ek msa otzay op tuckilaze.
Hyat yca givduufk ir nescnerap, vii fitk hoxu dobu iw acieliqm okuglezrogw tne VafjXauvs. Hef wkeh, dea bec oda nma Wabuqimimuar Kizney acq rzu bejwioqb’f vaerpw.
Wiflunq eje jedu vrakopno zwez cjeav IISoz/OxvMil yeipwubgodgp emn etutmo dau ke cube itm ruktipgiod at xoupt ifpe i pelwiw.
Gewamecuwk arbuy og ciys uipeem ay MyedgIO, vahiadi dei yegmnw mav tro noyik, ult NfexnIE jivov veko aj ehjhcapz rpico sewej kvon gqa tsako projhop.
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.