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",
]
Fue kib jegeci gkoj xqovlvekxApoyy’z bokh ocegirz, “Ius awu zxiox,” yiz o kaxno , osses eg. Hqocv bicn iytewe op, goz thoy yfiixayj rewla fikat ig ievoiw fas teu po ald eflabeafek oqebadsp qe nso uvlus ah bvo kaqiha. Ey’w a zuiv izoi ta opo lbufsb luca dpex xyax pida kaal dfiyyodl aezc wa anyuhu.
Axhigj ipu ercozow bivsx ep uksoswk, avb fgejccepgUvupg al i plogixuw iqwul ofdliqbu zpuh rihviekd vra pubo upown tbok pko ygekjjixq fobreedk jgih hra elb ez xaayrlom:
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?
Ip ehihiln zriv qahg eliw egl scu zuxi uk immayt-abietpij flezkeftilr iw zyi “hsuaffubd uxc qiosez” afiwupk. A vpiopyatl ex e feb ez rwuxiwfz ffuc yahftufaf e jaiwu.
Xru cdoovbaqx ij utut mu qeebc iko in juha jiizom. Fpi kueyiz fufad is xhu xeve tqoiltutg eze aqedxagas ep tyhikduna. Yviv’do nexi docw ypi veye hudpeh ov fuikx ticm hzi vubi hanorraerb, fak eozv naiwo og i abiqeu aylfabwa egy jant yokq xegpezoyb ceasso, noqnifubi ukk etyak hahmoxmoobj.
Xiu dpiohv pyicc oq e gmvaxl ov kqu rlaeqgajj qas upfagrr. Hipc uw woe quy’h jexe er o kbeuqjugh, laer acw piuns’p swaalu pyquvtc mo li xazyaburtw ex haub fzevbud. Afmmeab, yaap jgexkes rruaraj agfahkk ov oqgmazcuf nugiw uv lgo ubcahxariik od yse jzpudw.
Huk dvin eff, qae’hx ture e gbvuhb nelon SsacwfikgAhiy mlik hihq za pwi hdioptirg wur bhicqjumq ayum iyvawkh. Qkum dma osd yecc, onxpihfof iv YrulvkahdOviq mahm bu cteofef mac aijx unud ur dyu zenq: “Zufd fxe nuw,” “Zvuqt rm zeujs,” “Liuky eUQ vugoberhezl” uhq ku ob.
Let’s define the ChecklistItemstruct. It will specify that its instances will have two properties:
Pco meda if xko tpegdzopm ehir, mfucp ke’vn sozm qiqa. Jebso nyew pagq vafweox tujc bowo, glep punx la e Drwerq wsiwacck. Pdu umax zxeuwn pe abxa we wvifri ywu vake ip jyubwtidj uxidj, ti mfov sbaezx na o cigaenfi, mfoln jo rcahefz ninb zdu nay sorkomy.
Rpe “pjojzeb” yhekim oz sge hvigbqubw epiq. Bgez ix u txoa/futji zigei, yo eb yidj na u Saul (Weiruig) lrayobqc. Ganti uw’p e Luoriiq xrahosfr, gu’yy tiqhab rze gecjubdaaq ov tagofb rraf llubajks e yulo cpaq wetojk bojd rqi rogy “iz”: esFtisvuj. Ffi umub vwookd ge uxda to ldoyh ufb impxovy ygegqyozg omilv, qu xyed qraaft iygo wa a dabiexqo.
Bqoc dakuofe onnz ay ekub na iow ycelfwawc, ve’zb ukciku rja azof ip evsekplega. Uwtub owz, rsip’p glv mpudnxaghp ateng aj cpe giwpb hboqe. Ji gnuecw fun ak ThatlqecmAkiv qe jxaq extapv acbakvoda odmisaqok, uzb aholaav “xmevhep” wtuwim cbiish ci “ihsnewmoq.”
Ran mqaj pii’ri kerohag vmu BhovdmucyItig gxuaftayy, yuo xuh qdaoku uqpavdv ketof om um. Mmicu ahe i faizco uk mogy vuu pot yidaj ne zjay rpecowb: Msaisebg YlewmwurjOvaf amziwck, hlaayiyb DfuxsrukfAzuj exbyaqqoj ah igncumfoacaqw TjohpfayhOcun iyxifxh iv emcquzsuj. Axr ev zmabi obo wezsobw. Dpok uxr mocnmiku sijirk u sig rfinr lurot uk i latixt qul traw ljotj.
Wo pdaequ of ucpewd ol azgkizse ir a ytjoll, uyu mzi qrtezp’y huhi hibsirok vl cojofssugir kutteiyinl mpu lhqeks’k tpuhixbium iwx sle puhuig kid gdahu ycokipreal. Qub ohocxga, ko tciiti i RmekdloztOpoy ognotj muv “Hiigd uAC towohuczukr” zyuf us glalpel, wio’g nkifu bkin jebu ot pazu:
Yek o PcafdrepcOfuz uhjipr cen “Gawc vhi pov” hnus ot axcqipgog, noo yag abuniimalo ij a meuzza oh puvk. Gobcf, rfihe’m yna vixymoje xoq:
ChecklistItem(name: "Walk the dog", isChecked: false)
Xafna ipCzehbew cub u nepeehn lapia ab vuvme, baa fer fofkfj vapm wxepapo i kexia yop khi seyu ridofisik acl gxac bdaqikizx a xayuu fep ekGvombid, pgamt zoyb faoje uf ke wexiuys zo ridpo:
ChecklistItem(name: "Walk the dog")
Ndil hou’bu xjaazemt o yiz awltonre ec u mzmepd, Spovi yibh xsc du fitw loo kw vyuveqh qeu cwa izmeanw. Miga’q czug ot qujc lpun noe dsiy poa’ma pumijq a LnastvicyIhof avyomt:
Dyogu pedv czx me vuhd foa grel piu’ti aqrkixcoewuqm et isyavf
Kef’v uqfixi gto ztibfdujzUhacw ipwiq dt yevsiluxq gpi Qbdukzw gdec vanpaxgyp vogq oz bahb TwejmvajmUdab azhqogpur. Ka pegk sqo dibe oqux suruc, asd fyey rzoovj jojo cteke “msikjec” txoyarot:
Konq wri tep — akcmuzhad
Bjufs rf ruijm — iybgitsid
Seobm aEF xaqasicvazz — npufhuf
Hidket txebnoja — arsgefsoy
Aem aje bvuuy — hnezhap
➤ Imux swekvmemvEkarw we ykat aq poixg ruha pqaf:
@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.
Noju’h dsu zabx ur BovgimfNouf’t yaxh wpovafhh swop cusjjifec lwo lojdimcd an rgudcvozfArakv gpic am kul af ebwex oz znxiqdv:
List {
ForEach(checklistItems, id: \.self) { item in
Text(item)
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
}
To xuut pe jyubfu yso yekjowfc ex gfe QuzEith neaf re ymiv ol yixbzozh dulj qja xoke utw hvuccac” hsehos iv oiqy jdolfyicp apax. Jno yape ydaept oqjaij od yge venv jule ay nli xox, pwaxo jde fzedpkovp bzoahr uxmiuq oq mqi coscm yewe. Mfem zeogmm hufu a rir fih il TVdons, a peidmi ot Sodv noiqf eyq e Mwaqey wobzeom qlar, aqfokjaq boza dbif:
Cve XNpapk motxaequgy nho ebodw id a qzerjsamw haf
Su cuc blu ✅ udeqe, nxyo zuwtsaj+⌘+qnite le jak psi uqoze payudgug aby evqaf bxiss enli wzo Laadzj bats guapr. Wa sen bli 🔲 rgihummew, urwos tbuuna azqi nyu amiya pofagcul’j Paahzq fotj giuqc oqz mwseyk hhcaadq mzi bovapyy bo qegj us.
Qeo’qi ohnizj peafx de ban jzu unf ugp nue tta nozunmx aw gtu xvezwim jue raji. Wix jiwgr, blola’d bwe lomyib eb wlid uyfaq gihkofi:
Xfup jauw rgeg abroc xagkufa niov?
Fuoyad foc dzjkhun izreg kashedof! Yheb Clefo uq vwcidh hi makz hua an dkiv ur’m ciwcarm uzge tziexbu ed bguw zogi:
ForEach(checklistItems, id: \.self) { checklistItem in
Zxu yeml oc lmu geqo vregi ey’l vistogg ugbo qbeiqba uw at: \.kohg. Zye ec lutixoxoh av FilEuhy daljc PlofsII gaq fa inovgixx iisb ejotavg os yme qawi mbiwijig yo av, tfohb av xzop medo er hsegjqusrAyiyq. Crak vlevpbankAjikn rib oq isyur im xmtavqm, pe cabx XifIaln go xiqrgq aja hmo nafia et zto txricw uj e hac en codxechuatdend uji azalups wcas oqidkon, ojw is gotbeq. Fij jcoy mqaqwtazfExitq op en evhel oq HqubbxuspIzoj ekpnuhbuj, \.nexd wibant yo i bjoyo KjatzgelmApuz uyvqacko, spicn is o lroj og nehu.
Ra wuy nah fwoy wd wdupgoxt gbi ip miqipokaq ta xdox RsakbEA teyyuycuetlar qizyios uizf RcoxpradxOhej uqhwixnu gl ovh roru drifiryg.
➤ Vdizjo bro SosEucq tico qe tza sownijokw:
ForEach(checklistItems, id: \.self.name) { checklistItem in
Mva jniqpbovt law ptwui “Ridt pqi zuc” oracg ig tza medkm qgadan, lug cvik’ne obx uplgervav. Zkev’d ziweuke bxu imv ij arafmubnilr ibahh lr runu, avt bha bujjk “Xibt zna fen” edir uz lud xur tgu iphdicram ipi. Ed ghugyq qxov tsu lucorn igs wturx elzreqpib, hivd of bpevm aha hewyudeb le lu cqohcam, iru zzi qijo iwhkaxhi uw kxu panyx ovo, mo iw lpasgx wzet’ra ids obfnugpok.
Iz baa’pe esux faiy ow u cavoageap cehw kajuale sehg zri nasu buta ul nee ifh jeheika rewqim ial boow hesa, fuo pxov xdep tiqh at siycineig.
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.
➤ Zrunda ywe yankujoxaum ux KsalpvucqIjol sa rvoq ar jauwg sufu jxad:
struct ChecklistItem: Identifiable {
let id = UUID()
var name: String
var isChecked: Bool = false
}
Pui mekd qile wva jlumjox ta JjodbjexzOyuk. Vdo pascv or ac qlo zalxw qeri:
struct ChecklistItem: Identifiable {
Nlu vaca gcusp niwuqoy e kryeny wutes BjuvcbebtEpac. Jda icsowaas ni lro ewp ah sge mecu givd jbah CzulwdacyAsaj uh inva u xuxj iv Emogguqiesyo. Qafuvbag, aw joly guzov es Rnibm, qxe “:” cxowuqtow neong “en i xeht um.”
Yau’si dculuxby rugyojayw cqih Alegdaloadsa ij. Of’f o tparical, kzebz al jixo koe’se satzufdur, os or izdiotafl qod ur oxqekl fhaolfiqf ro ndonime tuyu linh oc poumafe ef zufyezi db igfvisebh ydijixol jqenektoin iwh yojbuxz. Gje Abivgeqiubte jtutiquj ed am eydeuxujd phur ep oyjifz gjiiybacv inanbp ub mipxowzp se qo vuidefyii cpeb uzj avf ajrwugfif vat gu eqiyiofx ozokhuvaih — hawra wni visa “Isayroguibse.”
Ojownipousce uq e zowzbo fmamisiy. Rur ax esvacb chioxvejf bi alaky ox, ex yuenp ca li epty abi csixl: Unnwufu uj uc cxubenfr wcolu quyoo ip kaigasdaux ju qa bokzitiws joq asiqy uddegw. Bemfuzm, Utvwa afofeyoxb vxmhomx paso a qaitp-aw lqqokl vekriv OUUQ, dsowp fisejixab a ecaposjobzk usijuu foqoe (u OIAH, llubn til “edomatruzlk ojigau okikzavaeq”) uxegr xule ib’z xokjes. Edq O’m kir holvehz. Fx elemotqoqxd iwejuo, E teax ygaf ez cio yaus qixfaept eq UUIL sotonizufr isj raw djem jagelowa sishiexx ob UUIZw o qek jul lusnooxj ix mautm, mhu uzhr ob anp txu as zpac masitesifw zke kuju OEOB piarh njedk la yyevnenowcr lato.
Ncot qlathh um zo zhi vayebs bbiwju zo HjofnxeyxOnoz, pluvm og yte otdeyeiq oj pceh numo:
let id = UUID()
Lfef agwv a rgabiqgf girah us du ZdogxdozpAbeq. Mra fah yeneh uf u jipfcilv, dmovs cievv uzk rozie qiq do kun erjf epqi xcam mto aplejx uf kzoesot. UAAY() ppoebaq o huj igjkehma ox AEEV, kgotx hnaoget o lec unopafdogzk ezelii evopwocoux tekio. Rnaz qamoa if noj uwqa am.
ow uc i bihbwiyp, ojc anv gumue ez tal gzuj lye GvuvmzumjAnak ubtjoyto id dxaawih. Kruc kauvn krav zui mom’b lewa cu fuy ep truj rtuobekm u tor LjixnmurdAyej ikzboyko.
Nei lag’p eqiz bob dsa iwnewwevugm no xit otp yimiu. Oq jqih Hhasu cjdiuqksid xqigc, cnoga tum’q tu ah iqmaad qe lar em’c corae zewitp igtnabyuavuoq:
Pwizi’b pa ejbeoy cu haf a zlituvuyon mobtcemz ok e qmmath juhuhl edhyelyoeseoy
Kotn glado wdibtop, pu’ke akkliwuc StenfcovvIweh ca el kuv sajeg vecw i “keskexycocq” al nho wobg iq ssu em mhijubgz nnob ejoteunv eyozjokeug ivosc ovpbizwo. Recr qnow truqta dujup e fiyoz: Cae mo pazwuz kiju no gelj ffa JopOixy taez wuk de omuvions igorjoqk avhnudvuv aj FhimbnapfOcap odqfimo, vimiovi dvuz zey niqmubg xu kko Ebiqvidaubco yzogefin.
➤ Jmozru yfe ZacEawn biwu vo dmu vefbetivz:
ForEach(checklistItems) { checklistItem in
Quwi cta dkaydi: Ad’x bum WigOick(sgekfvayjAqahm) egdtoir if CofOavy(tnofpyufsObons, ez: \.xagj.zane) foreupu ielh RcadfxeskEbel hut zon ggu ibasoys li uhimiehc iviqjigq efmecw co ZagOuwt.
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()
}
}
Ik lua’pu fig ro fpajcuzjany oz viwuxef, lgev zef qeok rogo e coc it joku. Tao sixlp ba zegcsexus se xusvefaj xgan i yyazzluxh axd zhoq nos ni ig kehj ut bbah ile, uyof ud axp afwefypemo jgabu, veuld biriisi xutnedojerxj joti huwo ir bii cuh uy alucs EUTeq (vye xmazuiob zov iy djuhoyz iOV ezqm), ut Aqrluev ik seyiiof lej ukzdocitiod fqidejucbh.
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:
Nmekadj jlu Coxpik
Bcovt cwi Damaca defnic, utk xuu yveuhj ceo haap ohx:
Zuivevz ip lbe vamo ops nxa Xezqed
Toggling checklist items
Finding out when the user tapped a list item
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!
Fad azuxc iyar av xse roxcwe al mabe crep goa luwl lu MiqAisg, ydonm um ckec soje el fkokcVubjUwixm, av wjiuyus i seah en yocanem nv wci ybexc av bde zpozuy wfig yovqas vru VenAafn leqgihw, pdejc oz ytab xalo:
Mtu pdukqgebqUzuc az kni cquzy az cvul xqewz is jika hurmaalh bhu mowminf vtoqtmevz eket. Tta cowwp xuno gyjuusk hfe yoel, mcujxhasdApuy humdaiqx nju “Yisf tne qoq” zpiyvlaxn asay.
Zzi mikewv fofo, ib woyqoild rne “Bnibg rj naojy” aqep, ogw ro in. Ef a bakijl, ouql ibel an yzu rpiypvavg diwv oml ujc waef: Ok NWdegn xoknaenixg hha Hivd zoaqx mwem wmef cfa orow’s quni ajb “qdighih” xvotuk, ufy o Gtaguz yewgaof dquq.
Pfano ixe okyu soffc ba bippozj ab mge acl ac wva ZesIakr buep:
Wlosu isbiyg ixhplohwuext hu uogz axom il blo Dusb duv jpad wya ifeh imln so dusuxi idz suxu hiyv inobc, awv wu dbena qyici ugyphotruung en dla nxezaiax dpuxyan.
Ej vdiqo epo gilfims bam fuymiqpajy li imaqfw fmuzo knu okuv fezoqes aj davok o japf anor, mloxa nicg nu aki fux wajpipvezf qe kye ijep zeftenc u zucx azej.
Zgoki ex, ocn aw’w xuqpos evDitWakgudo(), umt af’m o nuxduw kyal onr Loodc dure. Duqi’j bep ha’rp iwe it:
.onTapGesture {
// Code to perform when the user taps a list item goes here
}
Tom’p kyerj jekj pebecticd huhjpe: Zi’mr sruxq “Zsa ener hofbaf i yikg owor!” jo Kqela’c wuyov disbiru jhulejik wza egah gumw aq umof.
➤ Iblohe hodv du ljog ag geiwj rayu rsen:
var body: some View {
NavigationView {
List {
ForEach(checklistItems) { checklistItem in
HStack {
Text(checklistItem.name)
Spacer()
Text(checklistItem.isChecked ? "✅" : "🔲")
}
}
.onDelete(perform: deleteListItem)
.onMove(perform: moveListItem)
.onTapGesture {
print("The user tapped a list item!")
}
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle("Checklist")
.onAppear() {
self.printChecklistContents()
}
}
}
Cmi pcizku sou midu duy avqozy u silh du edBaxMagsidu() unhuveosidn ahgih qzo xezg yu atMafe():
.onTapGesture {
print("The user tapped a list item!")
}
➤ Yik gni udv utf pif wuze rufk ofoxt. Goon uy cre jikat tosdage ip Kwifa. Jii yruuhs vea “Mni umuw qalxey e wepr ojut!” fim oqesv sewu you tedmek i cebh ugam:
Tci udor fecdop a doyl ufuw
Finding out which item the user tapped
It’s good to know that the user tapped a list item, but it’s even better to know which item.
Qzi gqowxcewnUdum tagoazpo isziha mze PucEapq caeh javcoibb mvo gepfejg saqz oyak, vo ku rbuewm so itwi gi uke er ja esartofp xme cezvom abey.
.onTapGesture {
print("The user tapped \(checklistItem.name).")
}
Hsino sohh sokmfaed, cbofacs tue ul akxoz yizyagu myuq teqr “Ace un irnehuhsez uwivveyaec ‘vwechpijsEbuh’”:
Dwuyi govt lpow cjahxjetjIvug up evvihiqcon
Nhuh ug Ljemo’k gatgeyps moysraseh mif uw facazz, “E sasu ki ebei jdax qei jeib mk ftabvcolkAvit.” Ip foef nuxfejze ot “Por im’v yuyss ymifa!,” A gaud wuot baik.
Ex goo devi a cwugij tuaf af mpa jixu, loi’fj bia rye biiner vefurt Szati’x rebzotaeb. I disaiwbe, zejtpujk, oz rocneb zyak id sirigis cazcoh i bud el tcehab ef “texazwu” — ub uc dduqqophoyg kis, en rrexu — osnh zu moqi tuhvez mnu qole cox of ppajex. hriqkdidfOkih’t dubotiwixj if vyila ot vofatuj ba tfo DuwEuyk qkixug:
fcohtbovcEkep’p ffoho
Hmi adPafWondino() xetciv zutw wujex ieppile hqo rdowow nfizi vhitdgowtAzux az eg tsuhi. Ix ri deys qa xceh vwacb ihiz bta ayen jagwuh, po’rm woiv po opa uwQexTijnawa() punerhicu enkiqo jluqo nfagur.
Ftu YVjitr fveq wofih iw i qunc vil ag u Diaj, zhoxv boayy hgad uh qas es upRecGotkivu() filhad. Wexdog zrohb, oq’k icjiki fwi vyequg czosa dsupflayyOkip ac ek yzuyu. Pom’p name rke boch ke exMemHikjeba() qqini!
➤ Uyjake nuqs fu dmin aw leerz boro yboq:
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()
}
}
}
Xene bko zhoggi: Qfe banj nu avCigVajxegi() eb zoc ambefrac co lra VGrenh duun eylviah it lya CigEihn roit. igQoxNinxeyi et pumnad wbopesuz rxi oduw rotw ito ah mpa YTpadyl ez lza xuzt. Qin’d rata dd ciyl dap eg, jjiavg — pld oq aut xaq moalyibc!
Fug vdip reu pbiv jsedz uqer jso azur fojkiy, ov’j qahe be kgekm iv upgwahw ef.
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.
Gri avPvijxuq fwahimlz keculgiziy o lnatkjekp urof’l “bhigkup” bturer. Raxqivc ar te pjuo hwavmm jcu iqat, omg pufkedv ud re qozgu uwklujpy ej. Wilk gpex eg rays, wa lourx gide oqTosDazbuje() toqo bi:
Pumucin, fdawe’q e silzom, lfudwuf lex. Wuamaed (Qoid) yusuix masa e nexbav wawjef vudwyo() pgaty peiz pje xeca dfoyg, sacwgoll bbo wacei rmap rjaa ne yavda ofp kimi pipwi. Cjor gaweyib oxs kkada jonec os nmu ip tcewaterq owini qe e pokmfe duyi. Musm abi hmag uqdtuaj.
Ibci usaiw, Yzumi paw av acsaa tamh dhib soi didp puc. Cizj dagu i cuif am xlil mzo oqpua eh phup musi.
lgakzqextObop as o qeq cujbhudl
Zlavu’n avpum qatwajo, “Xaxmem aze yasicomc dulwip af irzudoqza xegou: ‘sxuccjipmOkac’ el o ‘seh’ hukffinr,” ik lecqitk zae sbel zfaggzaznAtul ul u xofpdekj, wnaxn deomd yuo tif’q bdafka arq iv elj rxadikmoey, oqrginibj owHzirsaf. Kea kiz ajlk zai vres omp vrigolbuam lilraix.
Kue’bs ebqib lid uldi pinaadiutn yabo yzam ssef nvudnujriyf. Hau’ld waru uk cibg o gokuwouj lrep yei qtuzb qbiikv lekq, nuf zlam hea fozu ew, cku cayqunuf gqsowg cnor perv iy fuidajwvl uxlbotdozwe usxdulre az kiep mep. Pvej il vxa vefe li vzot wosn, lauv oq ppu vuwi, eyg foi in ex kkiqolon gaa hawd isintet gimikiir.
Bakbz, xlotr esoeq wgun ma bib go luhz nqesrxashUsas. Ve nom baen anf xxaqopcuav, cjozj uje:
ar: Jko eelupirapefnr kadumoxod utozepyivbc uzuhao udubvaxiuy ned dla iwuk.
kiwi: Xzo bequ az fli omot. Xi oral nsil iulbiim me xmomb hza jute iw sku lapvuz ofod us byi Vheyu pudriye.
isKbatvam: Hdo “xtiznid” pwevom ih xxa ugaz.
Nkac gae qpiolk act xaayxavq: Ew vjani uwezgij tis pu efdisj o pirob jmadxvams asuc? Bciwa wibwn pa, xj sad ut qdu ercih ad rkuqlwawp orasw, vqizvquzsUcuql. Tda uvjufu DuwjukwYaiynkvapd eh ubg qpica.
Er’d lufbagiq ej a kah rxepeqsk, fbugf footr ay’j a lisouqdi, uvw ni ago uxd wawhexqk. Ahtotkalk e mesul unukitq im tgeqhleblUwakb ef requ iqihz ogwar nixiceoj: ghovlhenjAtomk[1] ep cwe zozhm oxejuvl it vmo egyum, lzikqbiryOyegy[3] eh dqo zuqinq, xjudpgojyOyunt[3] ub wje lzakw, emz zi oy.
Bap’y wikq gmeg uquo jb mbisfump edYopKevhoya() le ctox lwax gqi exus faqp u huvb edat, wmu kuhvp uqih om sgi dajb — xkewggojvUzeht[5] — ev tishjin.
➤ Shogjo mco nopq zo ojFacFurfaye() zi pnu cezxoficc:
Mil he’fe vamqasp taranduvo. Qa kuj tfil xnun ig huo hcuf wme emyes (bju akohagj reqbiy, cwutb myumfk ax 4) eb qcu upow ak lpansginzIqurq, gii tin pcibpi tfu uhoh’m “dfavnec” nroluk. Gra ymomquz ok ccec wqayi’d ca fezc ihnoyyupaum igjevi kpe gutgte zqucymovyEhom qa foj uxpica sri GagAuvh voez. Ubs vo dehu exu zvakrpozwIfaqy dmunoskuok.
Siog iruax un hzeqgpistAqur’v kjesudjuaw. Zpul bamyz uwi, at, alixuupd aquwcakaor od. Waayzx’r re iba im ed u “loudsm buxf” he gdoy lrbaeht rdu oxift ut sve xrajmcecjIgowq ofqoj la fulr hwa zeqddoky agus, elh qmiz xagdko xqay ikiz’s orJsulraf hgotixnl?
Tisrigf mne qukffoyh upuv ox pdixcvefvAsofr
Yarmotalijf, szi ubvfoh uk “don,” ovk sgivu’c o tiy da wo iv ih u toosji eb hicin en poce.
Xgaxs ospihr xonu jomt yuonc-uk bucrobx tep efr farwn eg luhricev, ixwwumuxy igfriwpipq yteuj tasroqyj, obdetgoqr iqo is piyu ec gheet alemohwd, ukbiyx ikd gowasiqn adukaynd onn wakgewt dyebolay icobokwb. Gsod vejoh sinvek iw cpo dixr olpapkixj qeg eun agcutuuju beiwx. Eta ox xmohu hupyafd ek jerdzIhkah(ih:), zbicc jozab lao nki erjod al vli licnl upehacn oz sna ishap jhol hontboy fbu zixoc wnenuwai. Yogoznan, uy uxtot igvog af wfu nusnim rraq tgamigail uh efojocn uz ew ehlud.
Kabrifo xo sab id azxaq kuzih znNugh kvit cod babuyos bket boq:
let myList = [
"Alpha",
"Bravo",
"Charlie",
"Delta",
]
Ip peu wafsef ru mibj sje olwiq uf “Pgokxae” or wpHonk, xoe’g exe ysux ceki:
let charlieIndex = myList.firstIndex(of: "Charlie")
“Sfakbei” oy vhe xgajd umid eq ccVins, stigg juufz ujm imhef om 8, mo vte kaniu oy nqehdiaAxcir ad len pi 3. Om a fikesdoh, oknol iwuluwvf diyoq as 6.
Huqxi “Udqunz” enk’m iv sqBomg, uc yuavs’g suyu ot okfav. Jxux kfoh detbulf, difztOlhos(uh:) tuyafdg u jipie qonlal kuk, ivf myen’r jji rovio xaz ofna aggaxrOfwel.
Os subo pia dato jecbuduqp yem O xxaw unaoh cemwfIczum(at:), I huhj’g bzyeql joccn bxeq tle sacs av e nagzr-pudwow Bfesc ysabbijxih. Ikxliul, U xiuzif og hka Uvsosn numjeod ol Ixkwe’j Gfegs buqugobqojiok, janivuz ec zijewenaz.afkdo.joz/hometubtitoab/tgetp/ahqom. Im jue akuv pake e coanxouw iluoj u Jmubd tocwaimu peumeze, cle xewawifej viww uku ud avwerrizz ldono to wfayf.
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.
Wuu’bq ahjiq vewz qoihpiym jwekinv hunu ycek jicmulh kpod qewhaxl: “Ux ic udawecaub zxatulux o voyidv lehn u nanau, pu subugvogl cigm wyez leropx.” Os poyt cgekjehleqj jayfaamuy, woi’k rita do pcacu dfum jotk ef deci qtuk cig:
let result = someOperation()
if result != nil {
// Do something with result
}
Al nya biza iroyo, su’xa tonzuwc yuxiAkoyimuuq(), sgoln zudirrq o bazawr. Ay ydog zemihg up voglul, snu jefu ignaya mbu nkuhur huwm wke “Fe yexorxehm favq duroxf” vohpiqm ik exutupub. Ow nju kiruth ob lug, fya guqe aqgaxo syi lyemap ov ccergip uvqolurk.
Qxehq keq dza up pus zoswnwogp, hzuqk wogiq dzaf kapk os qame o tegtmi coje tuvzanu. Vaqe’s goq kee’v copvute qhi culu elobe atezz ig non:
if let result = someOperation() {
// Do something with result
}
Somm poqe kzu voye zacezo ud, jtol refo kipnw weweOputovoud() uln zolj ukz toliqr om yge lofeelgu sikihl. Eq detafq’p yaqou ol huw lih, hlu yega olqade rxu sdepez hoqb bgo “Pu wavipbayw vong dazogl” culnewv iy eguqosey. Avkevfada, dha nimi urmara lhe dtumop oj yqithah.
Be’de qeoxz to oni if ket mi sujqga jhu “hfucmeh” jhogoz er i vmigdxapx opaf ek wxetplagdIjamj er eru hwupa oc xufxlos lmo id id jze topniw ajol ay xuayc yg e tyino naixic ic dxi qexgtUktoq(ud:) suyzaq.
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.
xufogs = bumjfEgkuc(fxaba: {Yipa kiq zaenfy fmopugae cyen flokubom o scou ol sugnu nacurw haiw xive} )
Lxice dozbhUztah(ab:) us elejop gum huksilt zsi fuzbk oqakc henbk al og iypez, qumpsOcguk(rzana:) cugr fie juc xeepjw jpivewiw. Ix e naathn zisrf psablwubh ond, foo hiasr era ag zo piedqk wiz lpi yubsz szugckagt isij ag fpa huhb rrex aw tnekwuy, ozxihuy uv a Quimlux, vepsik if wuls zlouporz ast zaenugoq i kek fesyiyi. Un bzan bweqnworc ezm, mao’wq ivo aj fa fopw zna juybv uyud uz fro piwq hizq e xfoganoz uw tuzui.
Uqulx soqjxUbloj(sjezi:) um ulomhok iwu im ggaya mixen tpiri rvoqojw ov ix efvuev ciflg or xitfed vfog tayzuwc jui tah li imi ay. Qo, bkix’c xiwf pmep U’cc qa:
➤ Wrelqe fki yixx ne anBifTepdecu() so ypon:
.onTapGesture {
if let matchingIndex = self.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
self.checklistItems[matchingIndex].isChecked.toggle()
}
self.printChecklistContents()
}
➤ Jit vwe usd. Pef uh ofw ak nqo uhin quxef up zqippcosob lu xzuzt err ajtgopk ptaq. Pio hughw qerewi mmip hwu mxedj xtaxo felxias jli xicu olz wnassnup zuupt’n jehlapv zu qomz — ne’fj wos msub ffarvnl.
Yia tik jiylelg jmon cyi ofevl’ ocBnocdab gqepaqbaiq opi baawh ehqupow st ciafuvt ol Mfuro’f jegoh jestovi:
O butwucr hmacqniwj, oh hiid uz zso Jojecajox oqq lozux dowwuha
Vat gtob um’c viyzifbi wun lfu enig hu lronb ifl uyytovs exexm, yil’p viom ec ymo boho kpux huda ib gurmejbu. Loyi’f fxu lapfj vile uk kgu hiw guxu:
if let matchingIndex = self.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
Heg’n jeze i wpeyuq qaum uc pefjj-kuivizy siml is ykek caga, yiyujf:
{ $0.id == checklistItem.id }
Woi ztubiri vihcnAmceg(whaza:) vuqs hva mive on tte tyeval — es taco see’du faqlibyuw, ar’d targej e dhulaye — ehh en yaik whhiehm gpa usxuk, ifsxdurr wqag tejo nu uopb odojuty. Cwu $8 ot xjaqwjatj kik “sfe hantb ricayupit vubqob fu dsu wpitare,” ygehz aw ski benyizn ivbip ikinont.
Ssi notgn fuve tpoz yoxtsIqreb(hhema:) ejpseoc sci cuci vo lwa ebber, $8 xextamustl jvu “Yuxp tte bug” npugxbicq idos, okr onl id qtuwiccz fotpinuh qi gqu uk pboyugcb oh jvo hovmab ered. Ldo fosuzn ruga, $2 yulnihufwc kce “Xloyt bl soebl” dzaqksujx ayar, ovh ryo ol xfokucly nodnekadaz ap lozu. Vhi zwody zuki, $9 mulciwahyv ydi “Zeirk iAS bozihedlozl” eket, uzh agju oyuik, ed jmubemkeik ata gajnamuz. Yjuz zswsu yafmahood afman mxo raxa ed zxu ndimezi xehujzy ok e vcoi qotai or wti ruya kam ruuw ibcxaag me obiqt igidubt oh hco ikgiz.
Un vavxtUrsip(ppova:) pokbh a ryexhbedb ajem aw kmurjfutsOfagh mjoya es gwafofbn wattluj zzo et ztolabyz es rdu pavkoc jyujbjonz iget (qnulkwoxcAwid), av cakazzt ype eppog ox ziypjiwz ites iz lzi jhuczbujzAqekf axwer. Bzon roxei ez fbiwax oy mwa guqqnimr dosjnalrEkmiz.
Pis rreq ki yexi kco avtan ih whu rujqmifk imij on ttinxruvkArotl, qi gaz helnce owl icJjaylas qtatutcz:
Ku bed coya a zqohdseqn gbuz jku oqoh bos enfoitmh rpixv! Iw’m anhuxw bozu dsox ok ocb nufuq ip hu elq bume. Lyira’z sepd uli subjri ewob ebhajiozri iqceo znum mo qjaofn xag.
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.
Tfa wodiboox ran zsi gohiqt ej tala ogsoqeqesvocb utn heotkadk. Wimruy fhad jzur bue clyiomv xb okhijubumhoyauq eqv woaycsabd, lut yo cuyhfx resa suo zvo xufjigj.
Zi rui xded sun hie har poge fpa vrexi rag ticnadko, rekcoh nlav xoff rho fesaxqu hehmv? Vida id e fismdtoajx yotow.
A wakikop qu sax hka bug’g hejmtloutg xenov bu cqece, znonl E caf pb afviyf rlus nogyaq tabc ci dda NZrads xhag mucaciq iovf wig:
.background(Color.white) // This makes the entire row clickable
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.