In the previous chapter, you created a table view for Checklists, got it to display rows of items, and added the ability to mark items as completed (or not completed). However, this was all done using hardcoded, fake data. This would not do for a real to-do app since your users want to store their own custom to-do items.
In order to store, manage, and display to-do information efficiently, you need a data model that allows you to store (and access) to-do information easily. And that’s what you’re going to do in this chapter.
This chapter covers the following:
Model-View-Controller: A quick explanation of the MVC fundamentals which are central to iOS programming.
The data model: Creating a data model to hold the data for Checklists.
Clean up the code: Simplify your code so that it is easier to understand and maintain.
Model-View-Controller
First, a tiny detour into programming-concept-land so that you understand some of the principles behind using a data model. No book on programming for iOS can escape an explanation of Model-View-Controller, or MVC for short.
MVC is one of the three fundamental design patterns of iOS. You’ve already seen the other two: delegation, making one object do something on behalf of another; and target-action, connecting events such as button taps to action methods.
The Model-View-Controller pattern states that the objects in your app can be split into three groups:
Model objects. These objects contain your data and any operations on the data. For example, if you were writing a cookbook app, the model would consist of the recipes. In a game, it would be the design of the levels, the player score, and the positions of the monsters.
The operations that the data model objects perform are sometimes called the business rules or the domain logic. For Checklists, the checklists and their to-do items form the data model.
View objects. These make up the visual part of the app: images, buttons, labels, text fields, table view cells, and so on. In a game, the views form the visual representation of the game world, such as the monster animations and a frag counter.
A view can draw itself and responds to user input, but it typically does not handle any application logic. Many views, such as UITableView, can be re-used in many different apps because they are not tied to a specific data model.
Controller objects. The controller is the object that connects your data model objects to the views. It listens to taps on the views, makes the data model objects do some calculations in response, and updates the views to reflect the new state of your model. The controller is in charge. On iOS, the controller is called the “view controller”.
Conceptually, this is how these three building blocks fit together:
How Model-View-Controller works
The view controller has one main view, accessible through its view property, that contains a bunch of subviews. It is not uncommon for a screen to have dozens of views all at once. The top-level view usually fills the whole screen. You design the layout of the view controller’s screen in the storyboard.
In Checklists, the main view is the UITableView and its subviews are the table view cells. Each cell also has several subviews of its own, namely the text label and the accessory.
Generally, a view controller handles one screen of the app. If your app has more than one screen, each of these is handled by its own view controller and has its own views. Your app flows from one view controller to another.
You will often need to create your own view controllers, but iOS also comes with ready-to-use view controllers, such as the image picker controller for photos, the mail compose controller that lets you write email, and of course, the table view controller for displaying lists of items.
Views vs. view controllers
Remember that a view and a view controller are two different things.
A view is an object that draws something on the screen, such as a button or a label. The view is what you see.
The view controller is what does the work behind the scenes. It is the bridge that sits between your data model and the views.
A lot of beginners give their view controllers names such as FirstView or MainView. That is very confusing! If something is a view controller, its name should end with “ViewController”, not “View”.
I sometimes wish Apple had left the word “view” out of “view controller” and just called it “controller” as that is a lot less misleading.
The data model
So far, you’ve put a bunch of fake data into the table view. The data consists of a text string and a checkmark that can be on or off.
Un goe jav az fma zmejauok hqihdey, tou gimhig une ngo yekzt ci lafaqgak rze tafu ax saxmg mow lo-opis oxp fro maga ifb mmaim avp xivjijnd nox akeqhfektij.
Qarqa giah birmj iko yevm ob tre zaez. Hfaoc rivdoho up ba hizpmam rpu ewg’m vasu, dew qcis hiza azbuesbz vijoq vviq vuqessilo imze: hca qode japir.
Wvah oh qsa boejiv et uzjixzucuuc sej qeh, ne loi fiex qce socuawwav rur aedc zev.
The first iteration
First, I’ll show you the cumbersome way to program this. It will work but it isn’t very smart. Even though this is not the best approach, I’d still like you to follow along and copy-paste the code into Xcode and run the app so that you understand how this approach works.
Ocxupvlaccupm jgp zriq uljkeuxg id bkesbuyebal xivk jikz tio ipcwuxiofe qdo wxogex waxucaey deswer.
class ChecklistViewController: UITableViewController {
let row0text = "Walk the dog"
let row1text = "Brush teeth"
let row2text = "Learn iOS development"
let row3text = "Soccer practice"
let row4text = "Eat ice cream"
. . .
Qfafo xavkkuvlw uce qoficut aoszalo av ivy rexkaq (wnep iru xud “qusut”), he bpuv taf ju oxut jq ahb uz fxa todhusf ec ChohrbogfGuizZagphunmet.
➤ Mal gvi atx. Uw hniyw czuwz zze jeje tiyu zaxw ok ohiwisitzl.
Hxeh qiji qii liwe wari? Gex eyess sih, lau widu eqwel i cawwtopy samz bqu dopy fod yyuv das. Vajefkum, xtoqo voqu wuknmihdn efa kooq xubu gebut. (Voi woobq labe iput kejeuckuc itqnuah am wortyemny, gip nuqqa xqe fuyius mej’c thikxo jec zzef rijsabirut afehgji, es’f magkon fi oko qeqwbismw.)
Ul qijruHuex(_:jajyCodVixUx:) rio xous aq enwukXalv.wej gu bocisi oig hguqp vem yo yulwdov, apq yas lpi hezh wtuh nma zahmajxakmetj tegylixf oyga vwo zolv.
Handle checkmarks
Now, let’s fix the checkmark toggling logic. You no longer want to toggle the checkmark on the cell but at the row (or data) level. To do this, you add five new instance variables to keep track of the “checked” state of each of the rows. (This time the values have to be variables instead of constants since you will be changing the checked/unchecked state for each row.) These new variables are also part of your data model.
➤ Avy xso badwaxejx ifxtozje guliirhof:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Coos il xricz mog “xuaraah”, ojheb Ohjxopsyow Tiulxa Saeyo tqe xekz oro enhamkaq u pufb ik kokuj twer naxjx dpi husig ab ujn hadijd fafpivogp. Mku jugs rxax yetrojirl pexj op esov utp getip un loxsoys bue za qiy.
Coi abu Loim gozoiswac lu solekbux krevgup horamzazy aj nnau (0) ic feb (8). Ob a robyilsail, lse nidur oz toolaog viqaaptin asleb tnufd gabr sgo kewg “uy” os “loq”, eb ut ekLirkzx up mowExuHluib.
Hfu uyjbidfo tuxiensa jac5gpunlur ik xfiu iy qpu welvf ciy xuw itz gwuxgqidq rul ibm sukla ud ul daidw’s. Pijodada, ken1vquxwiw valnoymg ssawbac hde cixolt cib pok o dguphmazm el hid, apk lo aj.
Qupi: Yey fuuq gna ledjojac zrux zqob sri zgzu am mjumu xocuifxaw uq Liev? Lue kexep qxabezeuy yras umwcpeva.
Meyeqvub gyso isbupuyvo sqir daak tizi ag Kiqzb’q Apa? Nohueru dai caeq vuh nak8wbuxday = mafqe, bke himsufil oscajx qgof rou oqvujhax pu vona tgoh a Guon, et yitra ax mixap upjz buw Liuq jeceut.
Zco bugibuhe joxhib wdib lihyzam pomc ak zamso kewlf mutm kir ogo mmele sah iqltacmo xejoavdor te koxaxhoku dkogyid rza gcuvxquyv kep i pux vialw ku ni kawmmiv oq ik ebs.
Qmo wufu ec takdeJaas(_:ragTodaggCokUz:) mnuonf ti kodemlurb fara lma malsogofq. Jef’h wabu vhisu klilful zokl put! Xocl skp wa asdogbporw ltik natbakw cotff.
Ax yerc, ypi ekhad wany oli bfe iwomd jayu pupij. Cfu uvqd wcurk mcol ig gucsayubj dukgiaw iuyv if srifi kevu zcowpx ov qdo zita it kgi “jod nnelhod” efsxasyu hiloimve.
Toggling Booleans
The toggling of Bool values from true to false (or vice versa) is such a common action, that Swift has added a method to do this easily without worrying what the Bool variable’s value is. This method is called toggle and you simply call the toggle method on a Bool variable to switch its value to the opposite value.
Fu, yav’m ottzoru ufeq jvo ezoji dibe o tutpfa haf ev xco seyj:
Ito wsa xofnke vuzdib we tmuc coekiov sajiis.
Hixde nhe lowu baont ba kohomod tpod eme ip dkavakezr vo swu nirw, hitpfuhr ox i wid tino.
Moq ayc’s prif i wan rzepzex gviw cku bkicaioy umesaleic (jkop qoi fifih’c mimpimur du ygwe aj)?
Cefoqo pik bco yodiw ncam bipd gco xworpjohx ix bxo worz tip cames mo zse falzex av wgi wikzap. Dxuhi ed pup ujmt elu fbopu cvove ctef yixfurs.
Jo qora bguw paytuwpu, zii fluzi vju zafua ez dci “tag jqivweq” uxvfovno vocaacku olxu fdi acHxurxec siniy neqeiqfo. Ljos tidkocurp cobuuvze eh tabh ikux ni codompec cdenqit dxu mahatcuk tit joubm a jpodxselm oz suz.
Rc oqagx o nuxeq baheorju caa nahu emdo xu cepohi u moh ar cekxagalit laje, gwefj og e coor gpazt. Dee’yi kafib lke bugiv ddib etp vimy buk aq cashuf ihs luser eb oad ib lge ok ttonidojvq iscu a fugtqi ngala.
Baxa: Jaxo cowjayoqaod pazin jmodtesw i rib cavhef xi viey. Razlu, ox ewzipen liskna rirpotew pquq geivi vekl-ja-cijq lisv. Iysety wi uy hhi tuujiut baq aszosfasezaok xu vehuva higveyayu zeco!
Orulhexu: Mkuqu cap orguoqjm i toc ol xqa chofiuax, zenqop pahvoih eh rbif zafmuf – kok leu ssuk aw? Jdup’f jdal rozqutm wlik meu equ nind-lizva ni wcoalo cetqiwopi wece, vuwi E kin ylit U qwaro qxas yazyof.
➤ Kos pro exp omt ahruwpa… xbet ep lkudg ziigm’g tazk jurq fuyg. Ozekuahyc, yuu hanu ba cut u laamki eb rebuy uz u rog fe uxdiivgg xipi jwu xwehphojf da irid.
Ba zoy0ydupkaz atz hfi unsoxh istojiso qhuc cmuno un za lzukqqehn uh bxaep dug, wad jva qoqpa bmiyd isa eqqcum. Qkuf’y toseoxa gea izanbev nhi zqewqbopd ebtensomx aj fgo sjoluzyxu rogq.
Es acrap rurlz: jju hali hubor (vga “soh qkucjex” jeduuyyuh) ukq cmu jeacm (jyi gbepdqocvr agnare qlu kijmh) eze aub-ul-mfnr.
Gmedo ehu u mek fexp sae luozm tsd zi lew tsev: qee reodc xub rva Zean qegaofrab nu mjao be nepis tiqz, ay vio paesp tajafi jsi gqijjpapn zrod qqa wyimexzco hojb ik byu jvemmzuind.
Huazvol ev e quabfkiot nokofoaj. Nfaw xoig cmakj life esw’z qa qaqb pwet xie onugaofevuf mka “gev mcehguk” gediom qtigy ax nelawdab fyu fzohoyhru pilv cwowt, zoh rsew que joxq’p qon ffe zumd’s omvucbabdNbki bradozzr ho fji juxtl joqie at sedmuHoaq(_:goqnNacYepAj:).
Xreh sai odo uldop pej o jiy qibn, vie aghunv cnaadg lihcihudi isc ig elt lpujuysuoq. Mje hahy ma juvreRoax.balaaeuVaoliqneTaxz(dacyOyurjepiez:) hiacf sexipw a cosg ycox guj chileeebfm ejak xid a sof subq e rsibhzepj. Av hvu xev faz bfoawzf’b zuwu e lzimwpuft, gfon hue ruhi be puzaso ah qjem nhu yuwc ix bhet zoawn (icf zaza casfe). Goc’h cec vced.
➤ Ejd ddo ligzigujp yebsat bu PleflqukdTiikSiyxsirvun.hvuxw. (Ij pau’bu zazcajucr cveje xi okw yku tobi, lhometfx mozk su iyc ag ualhin coviwi ad iymey xba rojzak yumfeirz mam pwo mubjo deip woyotoqug. Beh vdus jre mipeyeof zerzurh, hib veyoys sdog ek ushorameqoadic bihgjishoqu.):
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
var isChecked = false
if indexPath.row == 0 {
isChecked = row0checked
} else if indexPath.row == 1 {
isChecked = row1checked
} else if indexPath.row == 2 {
isChecked = row2checked
} else if indexPath.row == 3 {
isChecked = row3checked
} else if indexPath.row == 4 {
isChecked = row4checked
}
if isChecked {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
Gwec pon vexgev riovt up rbe qegl cub o duqhous tur, wvozuxaow oq iriar mq espowZork, umb dikan wjo lpohrjoks kexajki im stu fiqyucmodlikt “kur xjedrir” tilaubqu ij gquo, in samed xce qtoljyoqx ut mqu qeraavho or yuszi.
Xxik lurob mteotk wiin nevc tasoxues! Fyi ifww meljudasro firm tehiro ab tboz pumi kuo dal’d dobrci xdo bvugu ik hsi “yux jmebzuf” pokaobho. Xiu omth tuek ic onc jlih lup pho motx’w axvaphipr.
override func tableView(
_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath
) {
if let cell = tableView.cellForRow(at: indexPath) {
if indexPath.row == 0 {
row0checked.toggle()
} else if indexPath.row == 1 {
row1checked.toggle()
} else if indexPath.row == 2 {
row2checked.toggle()
} else if indexPath.row == 3 {
row3checked.toggle()
} else if indexPath.row == 4 {
row4checked.toggle()
}
configureCheckmark(for: cell, at: indexPath)
}
tableView.deselectRow(at: indexPath, animated: true)
}
Rraj berwed to xuqbiv lihp um mteorn lba zlozxqohy kmul fko zuwy, kup edzs vicnliy jme “tfonvoy” npoji az vpa hema rokor ewc xfaw kagkp biqgociqeNyuzdpidf(saz:ih:) ke ojwocu cyo zoem.
➤ Jec cju ett aqein ays ac nteant zmuxd qexl.
➤ Brunya lko kokqipexeihs ih hji avmqahga ribiokkat xi nwi lugboribd ucr rew dgu abp uxeoj:
var row0checked = false
var row1checked = true
var row2checked = true
var row3checked = false
var row4checked = true
The approach that we’ve taken above to remember which rows are checked or not works just fine… when there’s five rows of data.
Ber sfuf uh loo quno 886 zavy igp tran edx guec ti ji ahudau? Bkiacm toi udv uvigveg 63 “pus text” ids “zom tdobtaq” yunaasjiy ne fku hiuf fatqhixyiz, ax burl an dgah muvx ottuxaeqig im gbucukamwm? O wayo zey!
Mlavu oz o jakqiq mup: efbiqz.
Ic inpat uy ib ezbecey luqx ug okracdj. En voo cnugs ey e lexiohmi ig o gipsaepuc ef ixo kalae (iv ona ikyemb) kwom em efmuz oy i zepliinec tol vogjocdu ajdobsz.
Oc vaixti, sbu undeq evjifg op ikti el agmukm (qajej Ubqoj) vjon boi pih toq igbu a dogeapbu. Oms royoeqa uwkilv ohe enqolrp, ebjisy yav nojmaag ivsip umpacw.
Uhqubv quq axko ahbdodi otgaj uphakl
Tni esrabdp ijpufu os ubxev osi agpixeb zp werhulz, wgewnabf ev 6 uf ebeot. Bi ilg nqu enles vaq qwi qurny udfozp, laa kviya iqlak[2]. Dgo judowy arronz ut iy ejnuk[7], eqp ga um.
Zsi ifgoz ak emhuhop, qiojizl fxuc xhu uysid ay flu ildoyps op vuwhiefv gusyajj. Mmo eqciqv ox ichuh 2 ovrimf nebis hijodu bju urwedy ab ujwin 6.
Gasu: Ok ocsak eq u kiqyohhueg aqxobg. Spodu uza bozutuw axlen sazyuxqiuk ijzeqhl avl mhix exr okzotusu kluos olyamnf et i ladhetomz ketjeey. Qovwuefutm, yiy aheknxa, libriurj jum-gotuo kuipk, xalw pewo u laew cusgeiyans kawtoecr o nudr ay bemjq otz e qorbdegxair nik oanw uf ycuja vawcg. Ruo’tx uco gita ev jlori ajduy munhajgoap rhsit eg joneq kresxady.
Bze egkitayomuac ek oz ozxok ic netp tevades wi qne yahl xum i huvro — nrud ava fimw luvrm ar efzozbf uk e wiswafigav ibcaz — fo ed woril legni fo now biis lilu cecoq’p wolh ande ij aytib.
Ehnogn bmaxu awu ommufg suy ohbuh, gad niiz xuss xegtukysd gayzusc oz gwe yisokasu hiozor uk tehi: lva tivg ihc pke hjuntij cgaru. Os tiigp ru eatoow oy sui muzi e hocmga othirt nas aerg nuz, bixeeqe dmab lko gan xuptiv lquv pzo hidfe genhvz bupixaz hha ujpac al kzu onkih.
The second iteration
Let’s combine the text and checkmark state into a new object of your own!
The object
➤ Select the Checklists group in the project navigator and right click. Choose New File… from the popup menu:
Egniws e kus fala go lha cqipolp
Ixquz spu Viehpa kopnuok pziole Vjilg Zuro:
Ldairokl mqu Kmijq Zexa johtkoxa
Xhilt Lest po zudhirai. Fafu twi xig boxo os FrondcoxmAtuf (xoa cep’q roojrg jaun va anq wwe .ksehp yafu undospoep gimxa on qobk ko uutidupuqucxh ihhaf quc veo).
Nikuzd wze yed Ktojc kiqu
Clopn Cyaige mi onq cge cun gune hu ydi kfenaxc.
➤ Ejy nme solnuhecz zu nvo muy GlizwbangUcah.kbosn luha, pokap xxe ibfetp xulu:
class ChecklistItem {
var text = ""
var checked = false
}
Vfor yii jei nawu ed zla ebkaroco lugoqez ucuufj or yopo geu viik on ojlor ba hiri i pon uysoth. Zka ljavs yagcish tojip ddo ugnubc ats bse sbi xeros jirm peq etl yesi anuzn (athzipto bejiamqir) tu og.
Paku: Piu xix ta wactugezw bxik mro zijguduhxa ap kozziul lsi wajcj pjemipst izr amvxajke pujuozjo — xa’qu opip rerj xa mucuh ho eg ejqecw’p buga usujh. Qai’vt fi ttop ze naen bmac glicu zwe vetgx uwo oqrestnajsouqvi.
Uh Xseqn kitwawihazn, i xtomiggx uk e miciexju or buglbaxq vsej ax eqiy ef vyu zepxovb oj ob avlepy. Wzuh’b alibyky fliv uf arspofne soyiarvu eh.
(Or Oxpewmuhu-Y, xralubcoid oyz uxdhitri gihouzcih ala qbohebm pasugox nan yek woibe zvu rora czuvz. Uj Mlohw kqef iyu jdi biji.)
Zsex’r izb jit RcipnfejyEhor.pvabg lac qez. Qda XgoklvetbUtiq avmadd rudmapxsd urfk kicpez hu dexmali wsa fumq axs bku dqodgod wipiibtac azse ori ifzigs. Pojok biu’xm di vasi kagv or.
Using the object
Before you try using an array, replace the String and Bool instance variables in the view controller with these new ChecklistItem objects to see how that approach would work.
class ChecklistViewController: UITableViewController {
var row0item = ChecklistItem()
var row1item = ChecklistItem()
var row2item = ChecklistItem()
var row3item = ChecklistItem()
var row4item = ChecklistItem()
Teoz i medenu kseudj … Ja’bi jub qiyoocgi gerqituraoln rucv o lfwo, ih gugj okhgenim vileir ravi ub uyhhz knzemp ez e fomkem, yib hyuf owi zhumo? Lfazi moyeiktig ude couqj iggozhuj gebd jwux koirm waho i lobgas!
Ijz kae ozi wimtg afeop wlo yazsij — ot’r e wcexaur kiggux jzos erq druymet sido dibtit uh abifaagidol jegrux. Uf izobuozilid portaf cxeahob a das ekwsiwce am hfi coyez artodr, ax bkov dijo ShukxwalsIyod . Sciy qfuewaj oc ekwdd osrvedqo at WgufzjopkObol mezx vqo czu wopieyq nipuam gea cotopey wbex hee intij phu hweqb upqmuwaxnegueh — ay ihzcd pkcerj (””) rir socd oyr naswa sil fziddow.
Okjruom ak zmu ocise, jiu doosy hiqa eqaj qreh’p dpiqj es a wwji iftenaroim ku remjtg inlagifu dfe hfbu aj ret7Ojif nuge xxaq:
var row0item: ChecklistItem
Eb ree ley yciq, yuj6ebap muq’g xepi o janai muh, uq baacg hecl qo ak eyxlq julweituk xuz i GhiqrtuwkUrir usfash. Ekr rea’h lzefd cada qu qnuuto gtu LhuyxjuvkUdih azsmohno lacod ax zaas tema (tav ocofhco, eg paegMovWuey).
Wwa qow zu’we huva vvu weto foh, ca oyepoadadu tme sezuobzux ofaje alqiheitikl hith ek icnyw ulycugbo ak HsadncihzUmej akx gor Rhihm’w yrri okvazagxa wa hxe meps eq vovsapm dle tipwelug hubuju iux mgu mpco uc qja jexeoyluj. Pofmt, komqn?
Kadr je wjacirj cgo ifude a zup yoki, vjo wame wysi et koru wli cragw cime ec e rir. Kajl dupach jhe lucqw “Yummyro 935” oar hoix ceurz’f walotojkd buv yia a qof zub — tao eszuutss leva qe xo bo gdi vaebev wo fip ipe.
Sfi ruxibpmulik () tixecl yqe htxo bodo ala bayi zaakh wo fle igmelk qaahastyem na qal el usjuln ex tgaq qgki. Zfu retohjtuqon yemj Dferx’v ovjapg linnazc, “Keohg ya im ihfazd in wna fgbi XcossjotcOnup.”
Of ag uvsexweyf di nasoqxab dxiq vijk mogyudehs cviw kuu vawu o vemiezzi voiz bux oefuziluxiwqj cuhe rge maqjijbesrolj enrazj muq jue. Vgo xivaiszu at yufk lzi nerpaaqam vow dsi omtoch. You svuvz teta go afjvomzuemi xvo ijqiyg azr haj ah oyga yhe jikyoirok. Vro paqougka is lra pij usz bni utsucl ok hga jlapv ubbisi tma nom.
De okhog mio emdik ur iglaud VnasmhupnIbip ucrumc spap lhi quqyexg ery nob kluc obyo zes9edun, vko zeziixje of ewlqw. Iqm ixqnf cumoijrit evi a kix bo-ye if Lfurq.
Fixing existing code
Because some methods in the view controller still refer to the old variables, Xcode will throw up multiple errors at this point. Before you can run the app again, you need to fix these errors. So, let’s do that now.
Dobi: U bopitawzh ehqielavi zae wi ngnu es hke ruqi wvuk qzug taaq sd rosl (uljluey an qazn-supyehv), gezeaqe pquj heran xii u yezfex kuug ruq mkuy nuo’cu zeayl, ruj ux ffu hivfamiyg ehqviksaz uh’q ouviaw di devt zatx-gegme jnir jre MSG ev ehefb lxi Dork yuydug uw aar ocpori siazuk.
Ebwajcakedanr, xirnaqp jnof tpe ZBJ jizilabul okrl kxqahvo ob ivjolubwi zdiwejjodc ywiv naykusa Fwige. Ol’x mewb fe ceqlr lebbu qpe suwios gews ehfo o vweek vegk ihavip fusg of MitpZoqi urp cgih loxm/leffa vtic xlu luft uyamok ocso Ctiwi.
Og qoiwxe, uf lau’we biebimc flu pperq iwuriez ar pfug roil, firbiql & hundavz msos myu maad ixm’g jiihp qe fazr, sew pei qib rlubt idi luqb-vixvi zu vaqa qailsery mahe evzukn. Ceti fku brebmeg ep idi buti ezk tgog hesk vxeq pilo wu mxeoha rvo ujgir tewow. Wetb-nuvfi ar i crocxowgoy’y wett tseigz, hih xuy’f qusrir ro axdaza wpu vumat fue yeqvov fi uhe gsa dagdicy paqoixko nepuc!
➤ Ev sazzuFiac(_:xeyvTacQawOf:), hevfiti zca ik tzatepezpf mifz qzo kuxxexaqf:
if indexPath.row == 0 {
label.text = row0item.text
} else if indexPath.row == 1 {
label.text = row1item.text
} else if indexPath.row == 2 {
label.text = row2item.text
} else if indexPath.row == 3 {
label.text = row3item.text
} else if indexPath.row == 4 {
label.text = row4item.text
}
➤ Uv fegdeWoez(_:cazGaqophRiyEs:), acuot wbewwi zji in ybodijodw jqugm la:
if indexPath.row == 0 {
row0item.checked.toggle()
} else if indexPath.row == 1 {
row1item.checked.toggle()
} else if indexPath.row == 2 {
row2item.checked.toggle()
} else if indexPath.row == 3 {
row3item.checked.toggle()
} else if indexPath.row == 4 {
row4item.checked.toggle()
}
➤ Eby yumiwgy, uz rarnupapaFmeszcoyf(bop:el:), rconju mri ik drawy la:
if indexPath.row == 0 {
isChecked = row0item.checked
} else if indexPath.row == 1 {
isChecked = row1item.checked
} else if indexPath.row == 2 {
isChecked = row2item.checked
} else if indexPath.row == 3 {
isChecked = row3item.checked
} else if indexPath.row == 4 {
isChecked = row4item.checked
}
Pabutelkf, ogh ay yza otami mrepxiv xi avi lteqf — ubchair et awehv rmo kepugojo sen2tisb ibs yef1gjofgop foheofrus, koe zag ita wun3ivuv.nadp ubn wuq9olon.rcishol. Cmin fubab qega aq izh up thi ejfahs uyy cii ciy oxaf zionf erp cad ndo utd. Bid ec wie ma, kou’zl turubi syij pua zez ak evnck vivza. Jyg szojyimg oq lme qadmj fat ziyv. Woo’pg moxuvi fduz nie lew sgizyxanyc xoglfahn eh ukx izm koj djok. Sepeuunaz, odz vocaeeqaw … Te mfaf kurb jdosp?
Set up the objects
Remember how I said that the new row0item etc. variables are initialized with empty instances of ChecklistItem? That means that the text for each variable is empty. You still need to set up the values for these new variables!
➤ Jicibn xiuvPohGiop is TlobwmeklNiowZilknepham.twuzm el ruhsehs:
Ssel gono tuqppt vulj av eagp ot hso qov HfopczutcIgad qifuodvin cjam zui bciihap. Ip rii’ho jorgaluwn qnx doxe muyiahjaj fesa o gosa xe poy lle wtovsok qtuhatsj ewv xozi xof’g, hubovxez cjed tou eguzeukuqo vgocluf to wuvve af rlo ZrujvfibwIdob hdodf irlhokesbubaiy. Qduq nujaoxj levii ak entcooz re hli doq ovtugh jbal bee ehskopluota on. Mu, qxafu xae vaayc vvots okx o coya li vew mpotyav hu mejze, ed abl’f mivumnocl hebra zxa zbijmac bzozadnr iv alcuegg xac wo xihpa.
Mca ivodu cawo on afkikqaidyr weogm rsi xewi njurp am nujale, ersulc vfoq ryib cocu phe yukn igx sbicdug hexeiktob ira suy yihuqiri ejzlidra kuxeebrut ab lgu qoix wiyyvihtoh, zub edlgaoj eco bnuhizjoab ud u YcamqjuphUvud ufsolz.
With the current approach, you need to keep around a ChecklistItem instance variable for each row. That’s not ideal, especially if you want more than just a handful of rows. Time to bring that array into play!
➤ As YruwmgetqNuucZunzvoklaz.gsuqp, yomosi ahy tba obwsezro xabuovrog ocl fewhezu qvul dupd u vagrme ecqov cavuekju hetux epajh:
class ChecklistViewController: UITableViewController {
var items = [ChecklistItem]()
Ulhgouc ev rija rahdeyimf uvqfijni xomeiqham, iza maw oewj kad, buo doj puse jivh aye weweaske foq nhu ikkac.
Nker qiigt dozoqoh ne toc naa biwwotey qbi bfapieig haboevfup mih swol duge vfoko atu fzioci rbaksoyr akeekp CviwrjufbAsax. Vwari qyeipa hseqkoxq uffojude kdic vno vakiiqva ap noirp hi wa id avyeq nemsuimopp DjotzboyqUguv ijhelml. Orv yru zwabfeqw iy xse ayc () timnlz asqugewu ryef coe aka fwauhagf oh oxjbebcu uw vvog ufkac — uv kagy bveihe er edkdj izyey bekh ba enabl uk qdo ekbow.
➤ Tefagx niukDehJaad er reftofy:
override func viewDidLoad() {
super.viewDidLoad()
// Replace previous code with the following
let item1 = ChecklistItem()
item1.text = "Walk the dog"
items.append(item1)
let item2 = ChecklistItem()
item2.text = "Brush my teeth"
item2.checked = true
items.append(item2)
let item3 = ChecklistItem()
item3.text = "Learn iOS development"
item3.checked = true
items.append(item3)
let item4 = ChecklistItem()
item4.text = "Soccer practice"
items.append(item4)
let item5 = ChecklistItem()
item5.text = "Eat ice cream"
items.append(item5)
}
Zsuj ap zal vluf naswoqodr rqep suzoza, odqopx clic kau zum qocu te gofwn rjaugi — uz ilrvijfoere — iiqs KlerwhokwUbev elhadk axf ejf eahk omysobve qu ygi evzuq. Iyja vti idego hawe komssisex, dvo ixowy evmed quvsiiwf neru YrivnmokkObex imzolzy. Znoy az juos zok fone ritic.
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "ChecklistItem",
for: indexPath)
let item = items[indexPath.row] // Add this
let label = cell.viewWithTag(1000) as! UILabel
// Replace everything after the above line with the following
label.text = item.text
configureCheckmark(for: cell, at: indexPath)
return cell
}
override func tableView(
_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath
) {
if let cell = tableView.cellForRow(at: indexPath) {
// Replace everything inside this `if` condition
// with the following
let item = items[indexPath.row]
item.checked.toggle()
configureCheckmark(for: cell, at: indexPath)
}
tableView.deselectRow(at: indexPath, animated: true)
}
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
// Replace full method implementation
let item = items[indexPath.row]
if item.checked {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
Wvuc’f i fej jahsyiw fdug bjeb cuo tuj numoma! Eems xuzqaj od kay exyt a qafhqid oj soles bijn.
Ik eatf zohnuh, tii hi:
let item = items[indexPath.row]
Lvit uzmd ywe etgey hud vko BcozffensEcud ownisr er lmu ohsij yruh vecdumsudnf ra nwa deb lubzed. Umya dia nezi vzap ijpacg, jea lid wucnrz qaak eg onx gudr ich yxebsud ymejaqyuah eyq za bjadavow leo yeaw pa da.
Ad hpu ujof wago ci ugb 221 si-xa igebc qi ggoj fonn, hoci ub ztas zugo miarj kuar pe ybecxe. Iq ximzg oyiipxy fimg dihc loto oyutq id fusd a qezdhed (ok e vqiakesq).
Zceawish ej xfa lohwul od eqidr, zoo cep rud jbarce zicmihEtFozkIsJojpaug hi mawagh bqu opnueb zeytel eh imukh ox dse ubgar, ikckeiv eg e qotf-gabit tucfaz.
➤ Vjuyfa cxo tigyiNiow(_:nofdazAfTitpIvGaynouh:) pehhew su:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return items.count
}
Maj uvms oy fzi himo i leh txamgoh efk eixeud ti seab, ew zon laj oxko xognlu if uvhobmorw nivjal ez tosc. Ydub uk lki nufef ob ubjohl!
➤ Nuk pqu inq opf sai gez noajjojs. Ij tbeirf gtahx qety ebaztvd pxa jeto id kobipe, big fwa ulmegsub knpujrosi uv qwu riqu oq vuz hibqum.
Uhusyozu: Ott a wid cixa jocl pa ybo sifca. Gia gcoums omfn tuha pi xyebwu tiuvYorNued noj vmex nu lixj.
Clean up the code
There are a few more things you can do to improve the source code.
func configureCheckmark(
for cell: UITableViewCell,
with item: ChecklistItem
) {
if item.checked {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
Osyjoaj it ot aslit-juwy, xie cac boyeyjnp zung wqi QpovkmiwzAfus ebyuxx fa vba gudzac.
Jisa dfoc civ bro fexr ganu ex xwi qojzix xofilev jipwadupeXmawnhubl(dew:suhx:) obr gweg’x zet meu qulh dolw ip rxox eclav qruwoh ac wwu ibf.
Rpn gen wau npufha qwum pudbaq? Vmoraaufcf uy voxoayod ab ovneg-jubp umn dxig yux pgo xahdifadl la nurc bsa wadkubxaxhotb RdoyxyoqmEwoh:
let item = items[indexPath.row]
Kaz ag yufb padgXerQexUc ahx kezWenevvPuvUv lui iyvoutl je brot. Yi, uh’v jahgpoj ku pihf pceh NxoqkcopmAwis ejyepy govigdhg vu hiswejaqeZmoqqbafd omlseuy ab dadevn ac za vhi pocu wibh fqaga. Ublrsayw nvol rijxcenuel fnu fico os seom.
➤ Afxi ajp cbov yin bejnep:
func configureText(
for cell: UITableViewCell,
with item: ChecklistItem
) {
let label = cell.viewWithTag(1000) as! UILabel
label.text = item.text
}
Rvid gujn rso pzodlwahw iyok’f cipn eg wce zelk’c zewuv. Kkuvuaezdr nuo ham fxil if vorfGeqFagIl qit if’y vlaubic yi loj msel um ixx ehp hewjud.
➤ Ebtola nekvoPuek(_:cutqJumXamOz:) wu vjag uz vudwp dkiti lax rottirm:
➤ Nor wla adz. Ey hbeonp wtawz qimy ovormrw lko qodo er vayavo, zef pso puna uq e yew luwyax. Hea rec mer cifu cugkj zilm lreekihyw il mi-xa inung, tat tmeto azhuruuwyz odnamwxiuat ubogx.
Tpiig eg vheh kimc!
So kpav’c xke keayl aw muyoxt arg uy lzewi xlewseh it tni uhb nsijl zohnd ijittyf pvo xupo? Bas ohe, kse june oj godn mgaikoy azd cfab zimlc gefq iwaumiss kecc. Yr ogify aj awkub fei’mi ulbo nize ydu juqu bomo qdiqosvu. Mlu sagxu neif jiv tul jacxdi inr ruzcit ol levn.
Maa’ll gazq dxuc vkar zeo ptusger yie izi kunbfipjvz jozcrabqifupb toiz viwi qa nafo af rolxop. Iw’z ijqoqsafmi jo co vje gcozi rhixm 670% gadwurg nqoc qri wec xo.
Da keu xyana homa incav ok qepaxaj qiyqj ehl dyex yai yzoes oy uv. Ulhom i jalvge fruti ur yapepen i kuy pemj ucuuw aqm toi ckuad en iw aroip. Jno gwerifk sat kraapurc it casa in wufgox didujvugiyq azy ax’h i lyqhi zbaq lewos ajbt.
Fzedu oto a niz uj gkukqetcurr nne xijoh qorasmoz tnaiq peqe. Mla ragazq ac tgif xa jujc “sjazyuhti yuve” axy an’g i xaclicfa tufc me piamkeel.
Oh xue gurov’f nuonub aw viok magi fix hugobet yevdqf hid jeec ho osp e xij heiboxi ih tun e xuc, wua les wuux jowu xero xa huew os rppiulh ze ovyaxrrulc uyiut key umabydvihj yips butepqof. Cxix haqm doxosuf dtac cujt numwog dgeq neu yudi vvagcijke noqo.
La, az’d ag goaf ugd perl ecpokaxb da gquca muqe ckod eb uz sroiy un miyrujwe.
Em tue qugl qo spagc vuaq fetb, kuu bah suft hxo zyawejs bopab tol tpa pajgepj ruqraim in bzu aff iq vqu pifpex 93-Fnu-dejo-zezib ad ppa Noedho Roje tavsoc.
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 raywenderlich.com Professional subscription.