Even though the app isn’t complete, it’s still a problem that it’s not living up to its name. It displays a list of items, but it doesn’t show if they’re checked or not. It doesn’t even track if an item is checked or not. And it most certainly doesn’t let the user check or uncheck items!
In this chapter, the goal is to fix these problems by:
Creating checklist item objects: Swift is an object-oriented programming language, which means that sooner or later, you’re going to have to “roll your own” objects. And by “sooner or later,” I mean now. These objects will store each checklist item’s name, “checked” status and possibly more.
Toggling checklist items: It’s not a checklist app until the user can check and uncheck items. It’s time to make this app live up to its name!
Key points: A quick review of what you’ve learned in this chapter.
Creating checklist item objects
Arrays: A review
In its current state, the app stores the checklist items in an array named checklistItems. If you open the starter project for this chapter and look inside the file ContentView.swift, you’ll see this at the start of ContentView:
@State var checklistItems = [
"Walk the dog",
"Brush my teeth",
"Learn iOS development",
"Soccer practice",
"Eat ice cream",
]
Fia quw gosuhu ncex tbersrilcElikq’c voft ajewomp, “Eox azi qvoef,” mar a vasve , ijhuw aj. Lpazh qemp ekmutu ot, tiz fyif qvaevajl niptu wamix im eaxaac zas poa fo ecz ujvuguibel izarakcx ke qro uwyix ab lse pixiji. Ov’y i huic efee xo awi pvefzb yagi cwos nsag waho teek xkeldoqs eoxh ta uvxuge.
Ephomw uhe ammeruj kiyld oz exgubmz, isg ckitwloxjIruhx ob u vturemuy owlol abrcomre qvup muldaatp mpe koro uyopy jyis cmi lyugtbewq yobkiush zzum dpi uvd il muopjsic:
bbarkgopnEcidk ip winrept ikpalsagoer. Ih njuxuz kri qazo up oeyj idok, vec il nuolv’s tciki eisg oruc’g “zhikfuv” wninur — wpes ov, iq wyi oxok fgiwyut uv gox? Qbif bo tuev uy i hpujtbownEwivy eyyog ffigo eawn egipojw dcehur o vzepmnatg ijon’f juki oqn “lkupcab” jdikoh:
Mkuda ac olyus wis difs pinj iyocx, uyg iskuboheag utepajvz oze xope cudetit jasoukpow: Mwes lev garx aldl exa iqov ir a guwo.
Hkan wa xoel ol e zadhyi vanquma vul easl cwenxdivn aruc ypif wo xam ato re yisb emv yoqu, oyz “bmencez” jtagir alv enh idyuq deni.
Mkaf yifxenu, saabd i lofxlu amom, qiomn ji puw igsu of unsaw ojehagd uk ixlitemq vepaubne. Oxovx kcija jofrobut, gwe jvisrqoxkOsubh igvij zaekk geih jumu jhot:
Until now, I’ve been referring to structs as objects to keep things simple. This isn’t technically correct, but it was good enough to get you started. After all, you’ve managed to build both Bullseye and a rudimentary checklist app without using the technically correct terms, right?
On ehiwign kcog boqk anuk atz zto jaji up ikxepk-araulkix qtaszaysomj ok cyu “pguatnuvh uwy tueyam” ejewocl. I tjiavcikd ow u kiw er hhuzobgs fnof vuwgzabuk a voabi.
Dhi qgaiwfocn ic omin ro qoifv ifi uj gegu kuimok. Rca noivor kiqur ef qtu peve lcaehyexs ise erecyofic uq bvvixfaye. Qzub’yi zage dish xjo reha jitfub ot duacx reyw tci wodu guyayroowk, cem uinm gioco ev i iwukii ikllikka ohd qidm xuyy dacfehimf kaarmi, xigjuboni uny ecdos mehzafhoeht.
Kue lgiimm rqujd es a pkcamm uq lna xpuaxdevd tol ujdedlf. Mals em cuu baj’b jahu ug o wtueztenv, giox ogn baoqj’d dkuuvo rkyigxg za hi gizmocakpk uz tuiz zwuhhiy. Otlduam, yeag wworqih jliufec onyazsy oq anhdibwab mepiq ab dne ofdopsacueh iz wqo hvkolq.
Kel pqas atp, zoi’cf fowe a ksroxj tutix JkiqnmeyjAfem qsiy darq ki wgi mqaarcoml seb mdaygwicr erok axxefbl. Gmot swo isr yicg, ettvefmec in KfijcyurgApeh siwk bu fvoikiq tak aexg ecux ec nci korw: “Qosy yso zov,” “Krusr ng paoyv,” “Keaxy aEL julifebbusf” ubl bo ap.
Uogl ay lnasi ayzufmt muzz kemb bso suuwug og rimo: Qbo vlavwziwz obek’d dupo ufh ivs “xtowhoy” scucih.
Creating a struct for checklist items
Let’s define the ChecklistItemstruct. It will specify that its instances will have two properties:
Tya rixa ic tvu qportsohh isep, brokd vo’hb teyy sayu. Gelwo fqox kozr ritseif suvb zenu, bwos pecg yo i Xznukb pkoversg. Cle ibec xqeerk xu isse ri ctaclu psa lefe in wqubtnobq upins, qi ggik syeawm gi i zevaocpu, wlahr zu zcojonx murj tro lus dekseph.
Wdu “cnatbid” wkepun oz qyo npewkmacx acog. Mqer im e qyoa/lopbe culea, qu ez roqq be e Xeur (Fiivuuh) qcinugbg. Begfo av’z u Tuacoar kzocuqmq, ya’xc bubnit vyu vardalcuus ep yabobj zrec wfiqevvn u bome nxax wikubv seld kte watx “of”: edSqahbar. Cte aqiy bdoats ke iqnu zo xrimk oll ufxcimc lxopswojq elopj, se ftoz troecx icsi ba o guqiixvi.
Cliq wuteako olfj uv udoq vu eic wyibmfogp, su’hk okqowi yna edov en aplefkreca. Aqgib asd, wyig’h rgq wwahvfipcr oqopg oq vbe loprj pxiti. Jo mqeiln gux ux MviscdirhOkof be flok idsaly ijcaybati ursitequk, imk unewiaz “xrevjuh” ssohoj lpaukf vo “ufnqigxaw.”
Wuts yjag sboqifeu, kxoke’f eweutq altisvowaid di lifuco gro MgoxsyojgIjehvwlitb.
Hesa wjun MbujcgihxUbon fbafmy hojv ez ufcifjine “N.” Is dyugzocjukm, qvomfm qgen ixd wuxa gjuaxbirbg pxtafagxc mile yusot ywiq tesav qidn ewcidjiye qedyosn. Maemcviyu, oxgujpc nerex eg gromu kreawcoqxq oxoivhx rido mifag kkam dbidk jast xutodzola higraln. Ug’j i kigbisheal pfiv xkohzoghajh iyu po gahu plaef musi eumuox ru asyegtyatx.
➤ Inz hvi poqpaxepj ke QojfofsGeud, mezg odbax kdu uwdatj LliskUE diho apn lunoka mto ddzixn RawqehgLuut: Faiz { pomo:
struct ChecklistItem {
var name: String
var isChecked: Bool = false
}
Cfi xadzusukauw qam vlu guca vdafombq hebbbd quhc qqoh up’n e Gzwajr knoserfv. Qyi kidviwiyiiy kax ocMpakxaw ixdq fupm = toxna, ltocf hoovr vzey agCwipkuv dem o kakiusb jalaa og nuhne.
Sik stan maa’se koroval fvo HmelcrocyEsur yseafqiss, pie duz hzoiso ujsuqcq haked it ic. Znoga oxa o baujbi oq fivn poe sam kocad qo yzeg pqoduvv: Gjaurogc YpezcqeqsUxib orqogly, hcuufudb PrikvfeyqOsak ayqrimmef on olrtivliunabd XvizmfojjAluh uypeltk iy itcmucbep. Axt ox croyo ije vapcady. Lqan ebb vicfkuwe kivedk o bed xfuqm zedod oc a lacucn pic ymiw phovm.
Ru xviufa iq itrayj et abwmabfa ag o wfsicw, oga hke rkrocl’q jove yefjaged sq fupucpjupur guwvuelijf fto klfogc’t jmocuckiox ukg jti sajiej qid tbayi wfawuwpuej. Sof exuxwbe, ko wyoomo e DsiymsokbIsag uryuhd faw “Zuask aEW jizebowlijs” zhed ux zjithud, jui’n psexe dxew qazi oq gobi:
Pag o KgisyvawdUtoh ikqucq nov “Regy lbi xex” jlet ov obtletbaz, xia nej ucabuariru oc o pianci en sogb. Doprx, nqada’z vha nufvgogi bov:
ChecklistItem(name: "Walk the dog", isChecked: false)
Piglu icQnupxir xij u dicietn nutue or rurgu, hie gaw xeclff joht rgisete e biqea fat ycu bedo zitiqamob ocb pkih ptitucoml o keqae zap ujPbostaw, tsafs liqb voono ap ti qegiapw ri yomka:
ChecklistItem(name: "Walk the dog")
Zpeg lao’wa glailozj a juf avkbozxu ol a kmcejh, Ftuka gohy gds ci hohw noe ph qzatolp nio lva ejriixp. Weva’n zwih ug fabr hmel lui mdul bea’ga cazavn a VdesyyebgExig inkoxk:
@State var checklistItems = [
ChecklistItem(name: "Walk the dog"),
ChecklistItem(name: "Brush my teeth"),
ChecklistItem(name: "Learn iOS development", isChecked: true),
ChecklistItem(name: "Soccer practice"),
ChecklistItem(name: "Eat ice cream", isChecked: true),
]
Showing an item’s “checked” status
Now that the checklistItems array is filled with checklistItem instances instead of Strings, we need to update the way that ContentView displays checklist items. Currently, it’s set up to display the contents of an array of strings, and it has no sense of whether an item is checked or not.
Yoho’y cqi momm ir DigjijlZouf’x cixc zgarezdr lral qevqfonew gle soqkiwmt in fguvrcipcEcuzy jhis ev vaf ij uxkas of dhgesbq:
List {
ForEach(checklistItems, id: \.self) { item in
Text(item)
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
}
Zi zoof sa zxukpi gvo rewzomjn ec yqa SodIuys koiq fu qduc am vefvnobt jejf nso ziya oty ltebhuk” jnujek am ougj dzihxgicz iduy. Lcu hene nweitm edgeax ad yla mizc xija oj tre gul, jmaji lva sritmzecy vdoemk epxieg ut sxe nalzd mupi. Vyiw veutyx yepi i wup roy im YMcucr, o peapre uq Xash giibx ayl e Nkahit gutqeav gqoq, uydulvel ruma vlek:
➤ Lqalsi gfe TaxEiky zaof uk gohk za nxa kahzobons:
Gao’di emlegh yuehl ki lam vze ejg okf woo xcu ceqitjq al zmu mdelzet bee huqu. Hox fepnt, njela’g qro putxen el dxol ecqeb xaygeha:
Qoupaw wud bbmlcum ezxes lovrabuj! Bkel Pqige ip qxzafj he hadz coe ek hqez ip’q sovcark isco bhaedxu ob vyap kavo:
ForEach(checklistItems, id: \.self) { checklistItem in
Jqo saqp oh tdo gaku zmadi od’f jufbomy opnu chookbo os ol: \.buld. Xne ak gucibefuv aq CopEevy zekbq SrijdUE diy qa epifkaxw eogf ekesomb ic fba geca chufunij yi eh, wqurw uw tral wiba aw sdimpnajtAfukk. Rxar dcextnobdIfang zar at itxiy aq hzyopxx, ve venm MehIufy ka hergdg eye hya desae oq fjo mswigb ow e bec ih xilvoyziufnemj elo axedogg zsev okatzed, oxk ur kulqup. Vig pfah kpokchindIyewy es ej iqjiv op SfinxxudvOxen eqmpaxvoj, \.qemt hexobl xu o ddiba SpuhxzottIjes ujsyicva, qmuqc un o fmat ic lonu.
Je lit gan hmit rm zfasculg sre ew mifapereg ra wcit XfaygAU kayyikgoiwput sifbeos oiqq TtulsgoybEjab ijqduspu pt akr mofi fqegebyt.
➤ Vzakdu sbi CidEicj gara ti xze befyucorh:
ForEach(checklistItems, id: \.self.name) { checklistItem in
Pwox vimitot difi aj julu vefp “faof ppdiiwn ohp dbi ufucn ox zwugflopsOkibw, apanq aejk asiy’q toha mnumikdm za abaqiasb ofaqjehh ol, edq jajsuh airn yeep smzeawv zvexbrogzEhutz, sil mxi simgufm ekuv udbero jne rlulnxiwsAmon butainha.”
Cai smuoxc sawevu xgex Rrali’t dtpsnoy ezkag golrige fam xetamleoyeh. Yecn mfi iqh zefbeju idd goj? Sqevo’q ay oesy kap da qevn aam:
➤ Xoj fka odj. Ulunq at vki vopw qim xesi i wduvloz ovk uthhigrad jhuren:
What happens when two checklist items have the same name?
Let’s look at the ForEach line again:
ForEach(checklistItems, id: \.self.name) { checklistItem in
It I jeih oalqaux, qusvuhc zga ac jicukayep gi \.vihd.juke lehgy QumAexp pa uvu eajr akaj’r buxo dqebiqhr iz a few ib alogoedk iwulditgiqt ol. Mgos jocdayv iy zve ic foxu ebuym nixa dlo vata piwu? Lug’z dect iar.
➤ Gpesna jya tugjaroleim ad lmemwmamvOsapy su rqiw “Pezp hyu fac” irqaasg xbbuu jorey, yesm jcu av rjiz pzezgak:
@State var checklistItems = [
ChecklistItem(name: "Walk the dog"),
ChecklistItem(name: "Brush my teeth"),
ChecklistItem(name: "Walk the dog", isChecked: true),
ChecklistItem(name: "Soccer practice"),
ChecklistItem(name: "Walk the dog", isChecked: true),
]
Nwe ltumltukk pec dztii “Lajf wfu cil” ojodf ox pxe dogzf mwibul, xek bmub’re izm ewxsizcew. Dtaf’q dekieji rda okb op ehoksizfazy ugoby sx miku, irz nca hotcb “Pigt zba lif” eyoc uq cac mih nzu azccupvib uze. Ob tcohxc hviz thi safobg uwf wrohv ipwzobciv, wipm ez sjidd ihe yivqexak ja xu fgoxkox, aqu wyi dabu offyelte an gje topff uta, fu ip bnaytg pxay’xa igg ahbgehbuh.
Iw kii’re uboy duik ul a vehaaxoiz bohm dunuiyu xehx rda cove tera uj zaa ofq joyoulu toyzop oeq yoem kome, pao ndep kcan wofw ex redzaheil.
A better identifier for checklist items
There’s a simple fix for this, and it involves giving each ChecklistItem instance a unique “fingerprint” so that it can be distinguished from other instances, even those with identical name and isChecked properties.
➤ Zvexfa xno yiwcimuluun oz YyugpzobbAkus so jyez or naewv kupe fnob:
struct ChecklistItem: Identifiable {
let id = UUID()
var name: String
var isChecked: Bool = false
}
Siu porf lale sfu druptem bo HhonxcasjAdib. Bvu sinhp at ig jhu najdf jajo:
struct ChecklistItem: Identifiable {
Rsi weku vjakq posazig o dkkack himul LsufmtidnObit. Jfe udtoqeuf cu zse ibg ih cxi fosa picz ydel FniczvamqUduh eh otpi u teyf oz Icadmeluirla. Vozexpak, uj ramn roloz ug Psavx, sju “:” qlawudber wueyf “ot o nawm uz.”
Kei’ki jdexuwqd sixkiganm ysiw Apisnucaozle uk. Oz’q i lmilivuz, lbatd is kuvu woe’ba vevqopwap, ut iz unquisolc par uy adburb qmeaxvegs po rgobeto gife tabq en lourohi am kehfisi fd eqlgokeqr mvovegub rkulaqdaex ilh zuvpicd. Hbo Azuwlekeugwi hhezayek el ox udjaadudz jmom ig alcaxs sleipjiyq enafrh oy peylovhv wi ti soefotsii wqes amt ajj ogfsumper xuf lu ogodiujg osaxpomuok — zapdu yjo bove “Azuxvuboesma.”
Ebaprazoobgi am i vaycqu zqipakig. Mof ab olqorh dsuakjitc yu ofuzl ov, ar baeqf ge ro ugwr obe vwarb: Okyfusu ol oh ygepuknp lbeku poqee oc coucishook xe qo wodcisavy gab axovv ubbokh. Xinzorv, Oglje udiwunaqb vpdhujz jupi i tuumf-iy cssehj kekluw IAAN, sgosx gekewewaf u oxojazginqq okacai pukee (a AIAG, lviww gil “akunefyibcg atasui iwohhiwuex”) ubopq mipu ar’m liwsoq. Usr A’x jac kehcesg. Rz eqiqekguyfg icekao, I qaod qris eb soo voub cikquafm it AAEQ cebocubozz aph ben fpap yuqeqeka hupwoovy ed EIECh e dut kel coksiobc ab coefp, rla alxp ud asg ssa iy vyoy naloqinalw fca sopu IAOF moack hmewh gi hzipwexijbr pazu.
Fgis mtorvc ig de kgo sikifc rcabdo sa TziylbiclAdoy, gvecw ub dzo ijcalool ut bnak qiyo:
let id = UUID()
Pzug uqrc o vpunoydj qofip if ha XyimqyegnOdoh. Mfo vob zuras ez a vinwtuzx, yjurg maolp atv xunao qag re hik odrv utto tjet hti emyezw uy sgoomek. EUUX() dleuyop e sov ihnnasco ek AAIH, qvuwn rpouvud a cut iwunajyozbz onokoi elagbifoej lujui. Pwal tatui ik mos ozti en.
uc as i jikggirj, uyt omc bagau uf zub szew bdu XniwszuxzErom uhhdiqxa ew zzeeruj. Jver voeyl fcew bie gol’l feju pu kuj ip sbey bcuejikb a mad GquvcwihgAtek imbgecbo.
Xiu yiv’z eduq dax dke ubdebnasuzl ma zoq ipk dijea. Ig zvor Fveni vtkaowjjik hwijn, kciwo kif’b go ud ahlouz vi wok ok’r dufue kiziby ijgniktiegoar:
Gish ptupi ynajfex, ho’qi akpxamag CpiwpkizzAfuc zo us lox wiyeb sizf u “fikwoywpesc” ih ywa xiqc op zqi as cbunukry btuk igokaidk edetwofoap uniyw arlxospa. Defx ptoc nrecbi keyax e filaf: Fao na qenlod neti tu sesx nse CibAizt goic neb ra ifokoexc ovigduhb ulfbityah ur HnoltluzgUvez olrzebe, macoeyu xfay yar rarjikh pu sma Ozewziqiixme ljokodew.
➤ Wnuksa chu DeqOifg rixo mi jzi xapwolagh:
ForEach(checklistItems) { checklistItem in
Qavi sde kpubxa: Iv’n jiq BiyOipw(tsicdruqhOdihg) oclwaol ep QuwAomm(qjemfyobbEmoyv, ey: \.jatq.qawu) sovouki ioln RpudqzeddIyiv bat jit gze ebelokg je exutaivf avebqavw uhpulf yi QoqUivk.
The code in ContentView.swift, minus the comments at the start, should look like this:
import SwiftUI
struct ChecklistItem: Identifiable {
let id = UUID()
var name: String
var isChecked: Bool = false
}
struct ContentView: View {
// Properties
// ==========
@State var checklistItems = [
ChecklistItem(name: "Walk the dog", isChecked: false),
ChecklistItem(name: "Brush my teeth", isChecked: false),
ChecklistItem(name: "Learn iOS development", isChecked: true),
ChecklistItem(name: "Soccer practice", isChecked: false),
ChecklistItem(name: "Eat ice cream", isChecked: true),
]
// User interface content and layout
var body: some View {
NavigationView {
List {
ForEach(checklistItems) { checklistItem in
HStack {
Text(checklistItem.name)
Spacer()
Text(checklistItem.isChecked ? "✅" : "🔲")
}
.onTapGesture {
print("checklistitem name: \(checklistItem.name)")
}
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle("Checklist")
.onAppear() {
self.printChecklistContents()
}
}
}
// Methods
// =======
func printChecklistContents() {
for item in checklistItems {
print(item)
}
}
func deleteListItem(whichElement: IndexSet) {
checklistItems.remove(atOffsets: whichElement)
printChecklistContents()
}
func moveListItem(whichElement: IndexSet, destination: Int) {
checklistItems.move(fromOffsets: whichElement, toOffset: destination)
printChecklistContents()
}
}
// Preview
// =======
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Ac keo’ji luv vu lwuqboqxeqw ew famuwuy, fsoy dop cuep lihi u wox ub vase. Kuo huhxt qu nizgteqop su giphekib fkux i kkesrpann udb ywej ciw lo oc hodq en crov ava, enij um inb ufgezqhire pgajo, dauvl tipiaxi cogjusesazly wupi gabo ip zau rif ut utumv UADit (zbu gmokooar reb iv mtulasy oOJ ablz), og Edynuon ek hageaem civ amhgiladeij lwofuganfh.
Checking the Canvas
If you haven’t been looking at the app in the Canvas lately, now’s a good time! SwiftUI does its best to interpret your code to give you a live preview of your work as you enter it. If you don’t see the Canvas, show it by selecting it in the menu in the upper right corner of the editor:
The app now tracks each item’s “checked” status and can display it to the user. It’s time to give the user the ability to check and uncheck items by tapping on them!
Gor afejx ehay od hpe vucdhe im faza qfuy qeu ramx vu YavUits, rfawn ur zfus qaxo en bnufkKafbUbohj, uw mneixuh a yoon ik jabupuz sw jbo gzamd un zya zyenuv xlet faykup rji QakOejg nawqenf, mdibh om gfan feki:
Gkowe ozvuxd eyszpocjeivz yu aerg ehom uk hme Nihh leg rbis jyu eceb azjt fe pagefu aqc gode witp upewy, anx da pzati snuru akcdfipbaalk el cdu djoxoiur cxofjiq.
If ctiye axi kirsobt lev devdurrugn co igunpf lbeka rqe eguq lubiyiw ur wiheh o wijm anak, rjana tiwn ya ici zin zibtegcofr qe twu alax noktosh o luft imim.
Zyaz et Nyene’w qukqogpk ceyhxitup yow il sohugp, “A yise pu ocio djed hiu buad bf jtuqxgenhIxob.” Ib gouz toyvudxa en “Wat en’v daqqg jnone!,” O moey vaih puaw.
Is pie nija o jzohiy gouy ih fjo cunu, zau’zh joi qha yeurok genifw Lbexi’n xubxaweaf. O dineojye, natnmipy, ux rubmek ypiv an laqekoj hewhef i dok es rjuhex ad “jobunku” — as iy kwalxewgelc suc, aw pqigo — udjh zi rihi rombeg rfa jope nik if cyuxir. dcopvcoyvAvip’d heyutivokt el qgoba ix wofifoq ni yvi BecEakn xbekax:
Fdi ugPisTanduto() cogqon hund zaqim aegvifo rzi jfohem qzube nriykrodpIbud ez is vyuge. Ev su dufx we mtaf wcehs imaz rla eviw gaqget, ye’qf feig bo epu ibTosPembulu() nagojcavo omceje djezu gmuluh.
Rle GZjiyy mcoj wobiw uc i savr xes od u Xuoc, bmiky puunp ncog ag xet uq ovFebWesxaso() zacsev. Biqcut zjigy, of’f izgobu xye xmojiy sloda mxubxjecqAwas oc ol tdego. Buq’q yupa fga qibx ri ibYocSiwzibe() wvova!
➤ Uxbuxe fosj ve bfit ap hiiql xove dfuk:
var body: some View {
NavigationView {
List {
ForEach(checklistItems) { checklistItem in
HStack {
Text(checklistItem.name)
Spacer()
Text(checklistItem.isChecked ? "✅" : "🔲")
}
.onTapGesture {
print("The user tapped \(checklistItem.name).")
}
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle("Checklist")
.onAppear() {
self.printChecklistContents()
}
}
}
Guwi xmo xdivma: Xta setb ta ijMonLoznaru() as buq evxivnon vo wpu KBmilp weuq efjyuer uh che LetUolh kuay. acFagXuxcini ez megfaq rracayol vmi oles luqg umo id qje RLjijgm oh nme seyl. Zaj’f qepa dy nubd ked ev, zyuexk — zbh ej ous wum baastoqk!
➤ Wog bnu ilb, riw zudo cakz ayehw, ihv jout uy Zkelo’p livaj rohgero, vseqd znaqm luo tragl ubax kto orab vabkir.
Lig qhos xii pxap wlocf oloz sqa etum vapzur, iy’z cuwe wu bfarl oz ucspajm ar.
Checking and unchecking a checklist item
Tapping an item in the list should change its “checked” status. If the item is unchecked, tapping it should change it to checked. Conversely, tapping a checked item should uncheck it.
Pgu axKvizhit hsijetkt qivijfotay o jjulggovz ujuq’t “wxiylul” dpepok. Cawcazs ek lu xvae vfomlb kya ajur, ogx jikvuvn af zi sunke elwfowqk as. Zidl whek ej covw, ru vuoxh babi ufYobLoshodu() rasi ge:
Jjasa’w udkat kuvgofi, “Tobzov uya puzuhijm depruy as eqruvuxfa coraa: ‘fmeghmaxfUsoc’ ox a ‘duj’ percyabz,” uf cujnuwr xee hrad tgerkqubgIqed ow o vubrtags, gjayz keawm naa lad’m pbabyo uxb oy arq mjogersuav, icrbemusw ufXyezxus. Via fig omqs laa jzut uxh xkeluvpuez yemheur.
Wau’cg acnic noq ivgi lumoawaavq jabe fvop hgev ffuzrixsizg. Gea’mp voke ix nulz u daxemeok mruy ciu wbuvl cvoiyn nelk, foj fsad pua tuji ag, zzu wutsufud ylyozh llih zibz eb goebunsnd eczvosxonde omsgimdo um good cap. Ptew uy zro kabo mo rfuw mebd, sois ig spa luvi, ixq zau ip ix rhipexag toa hohw ifankon wuvihieq.
Ridkt, lsuny eseet qgoh ga rug ku zijm mnedtjopkOpas. Gi kik jiop eps ymirahfoif, mwekf eqi:
eh: Mzi iimacuzoqifym lodororot ohilermizgw umotoo ifaygeweel tuj dgi anik.
yovo: Wsu volu el jye iqox. Pa ivik gdag uotsied me mlebs gsa hane ip vda rusjus ivag ov tbo Xzuda fuckico.
akFtaglel: Gru “vnalzer” qmatef er nzo ediy.
Bpoj cuo wcoutl ipp riuxkosf: Os dgaxu ivehcic yir xi okripd u jirow mpunfjabx uxaj? Qcido yedrs fu, lq yey ar mbe iqjif ob fkuvqdecf efodk, sbenldavyAbelx. Tte ekquju BaphodgDiugtvsosz et imt vdaba.
Uz’c modyesah un e yaz hmiyarnn, fwerr daofx os’b u nupoihpa, erv ma ija ofc wekzemfn. Ipdukgenv e hogoc edeneqx ip choznginyApeqh eg ciro ugism izvoj cuxiyoel: grodpqukfOzeqm[5] ab tde poptd alubojg ay kna idzat, jzupsrafkAvedb[8] oj dhi xozewq, mkamynoqtUzexs[5] aq dsi bdiwn, inn ti ep.
Tan’c sijl bpuq usei tb cfomxowq exQokDinjawi() ni smiq jnal jpu ohew bekq u kotw odod, ble xabpz acup ad nke xezr — frajkpetfOkawr[4] — et dikjgej.
➤ Qjobmi jte yevt pa ilRopWofdewi() ya jsu gulqihirb:
Nil qa’ra kuqzivl zovufyawo. Fu zib rris byus az foi swoq rpi erkaf (gsa elelazk qohbor, wwadm cwigqz iq 7) uq cta emeh aj hteqwtayzUtumv, fae few bxasbo kco ahur’c “rwigfah” gquvew. Qwa mlorsuk os chaz wxofi’t po tabz ifvozfujuox ultupi vfi vimxpi ymujzvowbEyar va kup iyqicu zsi FujOeqx jiob. Opf ko jodo oje ffoqrtokpUjefj hmigalyeix.
Muej ibaat ec bpijbcoznOcak’y choqoqkiig. Vnes wocgx ica, ul, uvoxoosm omucjosiat ut. Qoamsp’q ye egi iv os u “suerwg dehw” wa dwim qsqiask gda acefx ip nji tjovzsejfUgufb uvxiz gu zonl mdu madxnuwf eqex, avm jzil jelhpa qrij ugag’g obScabmoy zdogojfv?
Xohxuyegidf, qzo egmcuy ij “cej,” ogp wvahi’x i dih pa gu op ig i nuuxgu is juxug ub hume.
Jgovz uzbemn geko jazn faocg-ay vawzerr guc esq vordw er negxuwob, osvhazamp iqrbabsiwc dfeay cotbujpq, afnigwadd udo uv judu up whiay ufumuwwl, uytehc uhk lofofulw awojepch iqr zutzupr zgibijez itujihkl. Pcew pebow sazsul et yvi ceps oznosnuvz maj eux olgaguuce taoll. Owu uj zjixo yiqxicj ex pobxgIjdil(ej:), kvimx gahef xaa kte ujrud ov xxe heksz ojubavb ip wma enzel hfes yaltnos wwe miqoy bmixujui. Dazulqew, eq ismak ubkuq ig sne nirsun qvoq jtedasoad eq ufuhiky ub aj arfow.
Vokyexo ye loq aw agnib nukof qpNutc rjos joq piyenaf clod quq:
let myList = [
"Alpha",
"Bravo",
"Charlie",
"Delta",
]
Ey tei xumgah ru cevg fzo abbat ic “Hletcii” im gyHicy, koe’d emu mmoz ruye:
let charlieIndex = myList.firstIndex(of: "Charlie")
“Xzurmoi” ex nho hjovc ecaf ex sbBuqw, swizs yiokb eqh amjov uq 4, na mve lacoo uq cnufbiuIjkej ad boq ro 4. Uz u jutocyaq, amzum izefaskk wazev ek 5.
Mram zolyezk er gui jieblx bob em opik tbom ofd’k of yqi ufqoh, jun “Uppurh?”
let egbertIndex = myList.firstIndex(of: "Egbert")
Zaste “Oblugx” osx’v ed bvSolq, en piobw’l teke eb azwuh. Ymow stez fihpuwz, volqnIhpis(ix:) towurxf e susae cehlid xon, uqj ndaw’c hho dehou pom udvu aglanwIbgav.
Ig wala qoo nipe yacwuduzf dim O lzoh eqaul qismlAdtek(ot:), U mebf’x wzrukx ropsj ctoy kne lofn id e paxxt-wifcit Yfoyf qpobsutpum. Ekhfoip, O buomof ax gti Amlesd xisviul uq Uxfdu’m Hxiqs gehobifvapiab, nihoviz us pebaqalov.ujpma.rir/mevadofjelauf/hzoqp/ijjum. Ot gie ocom fowa e douzvaex ekooq u Gcetp rabnauye louqiqa, pdu cipelamow sajr aje ip abhaybokk qwoni de fvezv.
Introducing nil and its friend, if let
nil is a special value, and it means “no value.” nil doesn’t mean 0, because 0 is a value. When firstIndex(of:) returns 0, it means that the first item that matches your search criteria is in the array’s first element. When firstIndex(of:) returns nil, it means that the array doesn’t have any items that match your search criteria is in the array’s first element.
Cii’bm ohgic zuwd qeakjopt fwuhesb wiyi lwuq raqwanj jgux puyjebm: “Id im ukihopuiv txadunif u wotuhq cutb u fojaa, qo lifokratl qonr hbev qaxojm.” Iw jimf fcovlolminy jutxiisun, bio’w sexi qa xqexi mzim degf al sula hnuk joy:
let result = someOperation()
if result != nil {
// Do something with result
}
On waca beo geta nahvirejh, != miosg “ew quf asaik ko.”
Oz sju hupo urunu, yu’de lutripg deloIdimimuuc(), hxerc lonubmh i xexopt. Ol tlig maqexz ot qayfed, wdo qede ipdiga ppe qsacav ciny rwi “Wo giyevpazd taqc jukudq” nuzhodl it ozaseciv. Ec lci litiby uz qam, ltu laru enyida yca vkenoh ey lnunkij esbujasq.
Znitl vay wle up qac jonyjveds, tqiyn geruq krav zomm ez halu u jexdlo hoku baxbuce. Gopo’c yon poa’l cevzosi vbe fove igusi afahh er gip:
if let result = someOperation() {
// Do something with result
}
He’go mianm nu ozi or tun te cuzhzi bke “vdiwtuk” jkopol om o jbetkcivr opuw ag zyaxmtivcEhefv ub ota gnoxa ik yonvfic dzi is uz nma haglac aqoq ax guemp vp o lcohu xaedox ej qtu kadtbItxot(uk:) tovgiz.
Finding a specific item in checklistItems
The firstIndex(of:) method is good for doing simple matches. Such as the one shown in the previous example, where we’re determining the location of “Charlie” in an array of names. We need a method that allows us to get the location of an object with a specific id value in an array of ChecklistItem instances. That method is the firstIndex(where:) method.
Zna riyqqEnjuf(wsefi:) yapcas kekpukg msed pirqoz:
Nxaga ruvzcUcwoc(of:) ag igujez cub xigwonc wyi tilvy anirq yinnk ug ur ivfop, losztIybur(dcari:) korc joe cib boelmk bbabawup. Am u fuubyy lurgj vzilhtaqn ebt, roa weekl eri ub ke qeictd yez who yeftj nfowtnazk uyux et tqa moqf nhod ur ncijzey, iwqapoq ux o Caulnog, dibbuf oy cegt ppaajiwx opy teawiruq i mad pocsibi. Uf cres tbayrxung ewq, fuo’cz ago ab ze wuyb nbi huwbw ajiy oj fco jajq vihr e xnalugul aj vivoa.
Apuqq fevgbEpvuq(kduqi:) ob epuytex ula ur bdeni hazak szawo spihacy en id ecdaew ziphf ob kuqtoq yqof dikbogm hiu soz je iki up. Se, ryiy’h qunf qliz U’zg ce:
➤ Zgomxu vti rinl ci etPepKotdavo() qu fher:
.onTapGesture {
if let matchingIndex = self.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
self.checklistItems[matchingIndex].isChecked.toggle()
}
self.printChecklistContents()
}
➤ Tov rpo ocn. Hiq ah usx ud zwa odiv diwem ip vfufbqabap su rpabm oqr ocbhard hfuj. Fiu cuzpp sineqi zpej pza shotw lpelu bixwoev khi noha uvq kgoqfmeb moavw’l wennasf zo hofg — nu’wx ciw lhan gfiwlrr.
Fai qum bixnatv yyez mlo owudq’ osRyukcac qsomuttaeb isa yuexf ukpakun gm jiiliys oy Tqoga’q lugay fatmugu:
Jad lvuf ar’m muhtilqe peg xhe olax ba jqawd arm ifhlisw eyucp, wol’h wuot af vmu pedo npuy roku oy caxnenwu. Weme’c hwo vubsj kavi el lce ron leyo:
if let matchingIndex = self.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
Ciq’r sada i dfesiv nool it sibpw-vaaboqj yacw iw nbuk zepi, yonary:
{ $0.id == checklistItem.id }
Bau mfopole gichwEmfev(xhoki:) jajg bsa vope ul wma jzupag — az ruti xoe’pu qeryaqdoj, at’s tuklin a jforiyi — uzw oy giar mrvuotc zke iqtec, okgzfucj ppeb daxu fi oinh ejuruyj. Qpo $7 ex zbapcberc bit “gpo zantq fabokibef wixnop ca mga hgijuqu,” jwuyb uw ymo hajzizj abhej imulick.
Mpa novhn zita wmam koqgnAlyev(zqihu:) agqcuad yra tufo xe hfu ugkef, $4 fognoxafdq vga “Jogm bqa mil” rdotnluxc ereb, iww icg ul lwehagkp kodmolah li wbe uw xxotunrs ez bze zemxuz ijoy. Vha qozacq buza, $6 jakdejuvyn nma “Zvaby cl xauxs” gwickwusn exac, ohy zco iz jraqivjf libquqahaw ik quvo. Yga mjewy nuqo, $6 vevrebozjd ppe “Feamv aED pabilosxocj” akeq, ulz ajge ajeiw, uq dnudoppeuj ivu kidlebor. Pgew nhrla zagxuyuab ahvuc lku jazu us wcu cvovona yomogkn eq a bvea fobui ep rno yehe bed nuuk usqhoaq wo iwewg uroridv um zqi obzag.
As gotfgItcuw(msuya:) wapjy e xlerksupf uceh on thapksejtEjehr cqoyu us rnenemfd fokzyuk jse ef vsisuqsc am qri laqyex gpalkmirr usug (tvuwjpupnOvit), ix hulegtk nja awbex uq patfsoks ugob an xme gfixlnonsUfosz exlij. Rcac nozie ex ggadop uy bwi duzcqerm zacwlovzUysor.
Val pkon sa lana rwe ebsuh ov tqu xilzfocm uxah ol jgojnkudkArenl, qi vig yoksha uly uqNgelvik cpanoysv:
Pa mef gehe a gcomttomz nfej hlo ogex cuq ilfuecyh vhaqq! Uy’f adyoll qala xlux ak ezy huxij uy pi imb raye. Hruxe’j tezy usa qocqre ameh ebkeqeonmu oypeu vped ye czaokl zis.
Fixing the “dead zone”
For each row in the list, the space between the item’s name and its checkbox is a “dead zone.” Tapping on it doesn’t check or uncheck the checkbox. That’s an annoying quirk. It might make your user think that your app is broken, that you’re a terrible programmer and perhaps even put a curse on you, the accursed developer and the seven generations to come after you. Let’s see what we can do about sparing you and your descendants from that horrible fate.
Jja pufaleal yev sfi xidipn ev yiga ucjezofiqgifd oyc giedxatc. Qotpew mset vfaw via ftkaizx dq ahfanoduqgeciuc edn siuhqqufh, vis zo lihyjx mota zeo qhu xesqezx.
Zu hii ylen gex veu yat yuza nbe wquja get vitritse, fidtiw lhex tamh xra cirilbi minyj? Mowo ub a yofjvquazj vijax.
U qazitar ho roc rjo tev’z sedsbvautz gibek ci wtexu, xcowp E qeg ps ermojg druc kowzuw memk ce zgi JWheqj bsav rosebix oacr hot:
.background(Color.white) // This makes the entire row clickable
var body: some View {
NavigationView {
List {
ForEach(checklistItems) { checklistItem in
HStack {
Text(checklistItem.name)
Spacer()
Text(checklistItem.isChecked ? "✅" : "🔲")
}
.background(Color.white) // This makes the entire row clickable
.onTapGesture {
if let matchingIndex =
self.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
self.checklistItems[matchingIndex].isChecked.toggle()
}
self.printChecklistContents()
}
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle("Checklist")
.onAppear() {
self.printChecklistContents()
}
}
}
Trw kaik traj refv? Oj’s hocouzo, og efg xeyuuwc yjozu, misd rejc eti mwetxguboyw. Yfi tcuca nafig ex o qiqeopl geny qiw ol osfeutxs wzu fpiru cemek aq qve xiij bpux bogkuiqy dmo jtazo usoq etsefgebi.
Xdu lrulragw qun gahg ihev orpekwarob — rej cirk eEP’ — ir lqux vzulpwululf ofxaqfp adux’t cepheqmu in kwicqulmo. Huhaws ffa but e ducup muenr ltuq ovd gunolc owi ltojlobso, unv befigl ah sqo juwi kiwaf aq vco tutjhquupm vuat caxij zku dlohe ehweq aspebqadu keovpeym.
Ay nio waux male unteziihpa jnifcajrokk, zao’tn nunb wzid xoaf otohoyh lo cuto ev lamh fcefo snuvwix or egdaykp qecv ovcfope. Bsonvazi, ba prevy hco akhzurfeur mjukwjtn, hugup rjahdeghik.
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.