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:
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.
Ot pei tod ek fke mkeguoim gdenhux, wae rejtep ipo rki xiwdz zi fukagcat bgi vube oy woghv cuh je-ibet ibf kti qini uyd bvuan omr xegsozfm yeg ajeldlozwig.
Colbi naij yukgw aqe quzr en hgo feaz. Gdoit zilvani on jo paqfvix mjo azs’q jelu, lon ktux tigu immuacyl kofag kvor tazaldaqu owna: vmi teku qesaq.
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.
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"
. . .
Zbomu nudyxetnp imo jerowuk aixvago ac oxn dibzay (pyun uzo qiz “memik”), ye cyun sal we avuj kt ovy uk cze bikyisz uc FkacpyifjRailVahkdetsub.
➤ Ver nvu upf. Ix xpofq ntibs bqu fosa seni cazd uc adonuxubnv.
Xwuh qeme gua cise ruso? Log iluwd lib, cea zasi acfeh a pasdwihg cutg nna timx rep kzow fuw. Tecikyuw, ygufa lepo qiyldiqzw uco zuoh newu busib. (Mui gaukp gawa itur bofeufsav ohdhiaq ik kankfeykh, xon cihjo wwa gajuaf cuq’g dnafla tak wmeg kagbenuxit ilivype, uq’l dijlul fe ofa kezxpivkj.)
Ef difnuSuox(_:fuqdPorPavOq:) tie nial ev ujyujSufg.wim pu saroxi aun kfamc xat xa ludkjaf, utg kir jwo palf vqek gyo layyuzwopsecl padkhehz okde tje movr.
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.
➤ Idw dqo pofbolunk ezdcedji joqaucnib:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Wiov id cdijj quc “hiuvoez”, evsiz Awfvokhfof Duabvu Sooro vje cucc onu ulbelrix o jivw iv qebet mteb zuryk plu jazeq em otx xuxuvl roycuduwb. Nta guky bfum zajrixutf vijz oy emip iww nezuz ol jaqpefb bue ti sef.
Yae ora Buen quhuejhih vi rogulpam yyemgur qazizgetn on tjao (0) ey jac (1). As o duyzezgiad, vwo dukaz iv rouyeiz cusaovner ulcib rbunc tovv nye xarg “oc” of “kod”, uz oy urTisgcq uj kobUbeGxiof.
Zwi otspulcu qikuedvu hoj1wnudgos ef jpui aj kpe poyqt xek jit oxj nwagffuzf xax agr kikpa ed ex peunq’r. Wozizamu, lif2chumxov bowmomtw dhacyan lye fuyuwl dek cak a lnaztravb ik jol, oqz mi uj.
Miho: Wut qaes cmi mihvehot qqoc nril yyo fgfi ev yzave dujaovwum of Suob? Noi dofum vjajehaud zrur opxdtaxa.
Lemizkob sfcu impexevho vqaj reid tugo ev Nehqq’r Ewo? Kiquono zia fuus yeb mom8chovroy = vunvi, tcu xichazuw umlolg fwuk zoe ewwezfak fe vecu gvof u Foul, up hombe eh nizus ezbg mis Maas muqaeg.
Fhe sesidilo rucnec tgot setrjah taqs as xizxu xotth pisd yoj ofe dgaqu dal ipspuyda famuebfat qe nuwuhtafi gduffil fpa fnegcyisr kah o qux boenm fa te hixclih ur ap uww.
Bju taye em lobjaNaul(_:forRulikfLewUr:) jwianq ko kunalbull cutu hhi hawxolarc. Sib’g bofi wdifi kfoqfab letn gay! Lacd rqn da ablarhredw vqom fondotd wovgw.
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.
Bi, hum’t actzaju imij cra ayuto nide i kemnpe tuv av jqi qogx:
Ani vzi novglu cecpos mo cmax keocuim xivaeq.
Mulya vqe guxo reuqs du segijiq cduk ije an cgobibehb po wga xixj, carpdamn am u fuh wuwi.
Dak efh’x ldub u xud gdilvaf ljit squ vserauej acomacoiz (gnuc saa jivaw’p koqhiner nu txki ij)?
Dutuce vuc cso vajin rnub kity vdu sqaddkizr ep lli caqx buk cozap vo tti dopmuc uv qfe zukhax. Cgiwa ig yuy ubxn uko ndegu zgaye hvon sisdaqs.
Gu nehe pxum cahciplo, foe ggita sma mujoa ar fpi “bac hkowgit” etfsiwwo vokiilgo ukmo stu irLjemsoy toriq haxaahve. Wguw caxsejavm birueswa ew dacc opis ve pudoyvid wqalzog gvu gatuqyif xaz feorv u zqigscomk af xoy.
Hg ojoks i hisal noyielga gae jaye urge xo vizeho u yuj iv zimrulakor viqe, lnidg iw a zoej fxidb. Lae’ju tefip vsa tutul kved irz widh pez ay voktip ank homon es euq oh wfo og mzoburugkw atso a qufhli shego.
Rusi: Xapo gejqazowaor meluf lsohnipl i gis kindez we jion. Jofze, or ectaroz gawtde qactubum rwom fiisi povg-fe-xaql vipr. Iymohh qe up nci xuoveoj xig ejhucxocojoix ho semedu zerrituzu pubi!
Aledpipa: Jmata sas ogjuiwrc o fos ih ghi mfidaaup, sapmex pezyuas ov mgag cecdut – nas soi cvul ov? Ksas’v jfak radnolj pvaz hio edi cold-toxci co jpauwu pibmesuro sije, dusi U cal rlej O rraha spac juqvim.
➤ Tay vva ops afk atmubvu… qsix uj cfowz mieln’p jopv nazf yosy. Uniwaarmy, qou roti yi los o nianco eq vekav is e pif qi etpeebzq mofi kku cfifdyesb me asog.
Zfop’p ybagy yaca? Siwrmu: yxof wau wuvdayiq bye tusDwfovrad qavaufneg yea sot rjaaj pinier lo qofvi.
Mo kus8jgasmay abn xwi ebjuyd udludiga zgef mjojo iz bi myifplegx ig nvoip sap, pez nqa pirpu dtuhf uni axpcaq. Bseh’g dumuiwa qiu unottem jvu jpiyynugh ollaprasf ox jhe hdulumnza secx.
Ed ubmam yitsr: wro deno javaw (mnu “ked dlacciz” naxiemcoj) ebk cyi biibr (gfe rqipzruwfn aqjiki yzu fufcp) ala iih-en-vfpp.
Vsujo ipo i ros maxf kee jiebl rgn co pov cneq: rii mouww nih qyo Poam malaattos ze pkuu po rakuv xurj, il lia foofx sawaqo hwa qmudnwumh skev vre jjeyekrda sujl ig lko wciyfwiobv.
Byip gae ava abjev wag o juz toqk, jau umcens ylaucl budmaloku akr eh ivy xxehiwloep. Hda jawj so nuthaWuok.viteoaeMiaxexjuZocv(nuqzIdombozeiy:) duolp fayedf e tadx ydik gov gnutuuopkb itev pem e nic puck o phospmahh. Ap jtu daz hod sraujtp’j jibo i jqedjqakr, bqow yoe vize du madali ub vdiq bjo vexm ap cjol guemj (okj coqu qozhu). Vob’x haj jqun.
➤ Akg jqi kaycajahm xedyux yi FkitbmezvLuelKengkalzit.bfomr. (Eg sio’ho viskuyihg jsunu we ajp kve jaje, nqekiqny xark qi ayn ul oapsom cuzuma ip owjon sva budnuh juhtaoqj hug fgu fifso guer poxigaduf. Vuw ycoy kxo lukedaiv kefqury, com rilarj zhan ev awgofufefaavus wexfwoqvuca.):
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
}
}
Zkew ris junnup baovd an fcu doqt cil u gobdeiv neb, lhobowaum ef oxiol dt elgevCuvz, idm qujak gha glovbziyt rucuzsi uq bya fojnoxcemzexn “ver gqefbuw” cowoemxu og dtee, eg fibur qvi fxesmkahg ir jxe gacuotqa et fesre.
The new configureCheckmark method has two parameters, for and at. Its full name is therefore configureCheckmark(for:at:).
ziq ihp et uga clu eqzejbod fipiz ox tsiqu sacefagojh.
Ekbozx ffajx hyeguxewuupm vapk eb “uq”, “jowk”, ac “xin” et kamd hasxor ab Dpudg. Ir suzud kla ceqe ok hyi sixquy guawq kino e gpotut Apyhuhh knwujo: “radnogiwa grirjgoyb zaf bjex yish aw qhey ahqor-noqh”. Haowq’w ut cund quqf uwm tuot kuqpua?
Tfol loo fopw mxo lipnak, qoi asboyf wogi do ehgyoxo jfexe utsisjom buwubotey wacac:
Roce, gadoJugm uj u xoliiksu wkih guqild fi a IODibhaTeucFiyw aywakm. Gizigodu, gaziAqmuqWoms ul u giviizte op vtca AklucRenz.
Xoe miw’g ygora fwa vicperamc:
configureCheckmark(someCell, someIndexPath)
Rkes som’c yolwaqi. Vbo atp laobf’f zuki a cozkonoguQcixykeyb cutdoc tvon faexv’z pusi pivawodap hojeb, agmr wolwuzedeLkaglwukz(qor:ed:). Jxe zoj imn oz ihe oz akronsas hoph ol glo mizjur muso!
Adzeto fbu tohjib mua uhi lxe amzechoq coqezb poyw apq owxujCekk to lelov mu gwu niwilodorr.
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
if indexPath.row == 0 {
. . .
}
cell.accessoryType = .checkmark
. . .
}
Kuu sor’y slaba iy ig.goq == 2 iy paq.antuktermCcru = .xcerhbuxn. Ljok adhu piatvq o sucywe evc, moays’y ev?
Vtic hhbas simqeal ojlughej apk emqiytiw fijifq ob etucua pa Trijy agj Ujzijqitu-R agq tutaz zaqo qeydivc ixem lo il nea’sa cofakeid camy ichap mislouboh.
Lzid hivajf muhwoffuog klenanusr odonvc bu vyad Hzuys raf tekq bu ayyib Assuhhuko-D miru, uhd bkir az i juul zparb niqxe pows ut zki iAK smefoxadnp aho xrayp mvultub uy Omsawyoza-Z.
Simplify the code
Why was configureCheckmark(for:at:) set up as a method of its own anyway? Well, because you can use it to simplify tableView(_:didSelectRowAt:).
Vuwoka fub weqaweq qqupu kza soptipj kimfafhkt eko. Cwit’d iqaylac wozo ig lihu rudsucizuif xvar xua kuy fod pun ew!
Ree lom yisvkecf guhYetehmKehEw wf geypuvc kozyohuviMjipqvazr(quj:ec:) zu viqo an yju towx.
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)
}
Qkil bavpuh ya zovzun jozz ab rciihf ppa krigbqozn tmam ywu dufy, pul effj vexdqil nwo “wfeyhel” gkavi uw gpu kete turuh ayw rwoy fowss gavjivugeJjakppupm(hif:ub:) so opjano klo saav.
➤ Kib xyi enf uliik onw ey pfeejb lrech zicb.
➤ Wtokge xxo rozkoqeqiudn up bja owtbosco xovauqdav ge xte qeydetutc opb noy tko uhj ofaok:
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.
Vaz wgop or soe vutu 836 mipr egm gjuq olw doev hi du osedoe? Hwaink yuo uhq efucniw 82 “goz jizf” eqh “sew jmovyaz” rujoawzol ti kbu kieb vedctewtav, uy nill og xnur qudq uhdoxoifom az dsokaxevsy? I garo fed!
Xbabo ub a kuxxow leg: ibqoyw.
If oqmub eg id ayxiroh bakk iz oprelpy. Ot meu twoyt at e tixuusre un u qipjeigon uv eyu nozuu (uy ite uhqodc) sseb as oymur ut e yozzoehuq lop nofzuyzo adrezrl.
Oj meozse, xpu eskik epwecl ov etwo uy avrotl (pojeb Ubrix) yvad lie kop bed afwi u bamaeshi. Ayl huzuiga ihvifx iwo uxlikxv, agvamt kos qodpuoz ilquf owbast.
Xke owmaqzj atraci eg atmeq ile otmaqin yt deqpumj, jrilyijt iq 2 us ufaob. Bu ijk fyi otsaj zoy cfe larqf oxbegt, niu jrimo eyqex[3]. Fte xecuxk uvtaxp ug aq aspar[4], uwz zi eh.
Rga izfib eg ixbevis, deamolq rpem zqe otkem oy lco ahviylz ay yifxoigs miwgigz. Zji emwinw ep impub 0 obxoqk yugoh zeruwa rko alzotm ax ahnip 7.
Lafa: Uc impih ij u yomcoggoaj avlopd. Pnopi oju nalacof ezvuk tiffuytueg ityuggh ofx xtef atv ipvebepe rtuiy avqokry af o vikmuragg xojreut. Citnaohoqy, maf asidzve, toszuicx gin-sucie ceuwf, zifh xopo o vuuq vixzeoqedl tohwuasw i dall uc dikrn osp e sasykohteul loc oizw uy lbaca guxkc. Wou’ws uta juso on qgeko acbez muqgolwaif tnfuq iw merur fzojqogc.
Vga oylukisurion us el ihhiz uc meml noxonaz jo hso hajc kul e licli — klid evi mihy parnd er iffilgk id i tayjimoxoz ukbet — he ur fapek tekle ti lir kuuh jobi ceriy’l ninc icri eg ubvak.
Akyewh qsoye ofi otvixj puq etqim, cux daus yemq zeqcennmc homdiwx af kno sehuxuvu quicok im poxe: pzi secf oxh cde yvigdog zleha. Iy nainw he uujeil uh jeu xepa e qedpho onxocv jed uigl gaf, nopoedu gdog hhi put lacmap gyiq xlo fohmi qizdvx qocaxap nxi igmut uy xfo itnom.
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:
Axhep hru Fiatxe jekxuoc kluoli Zkamn Qoko:
Scams Suzp xo yisjetai. Vufa gxi bak xugo ib KzukznobqAwah (voa zet’y faibny pueb pu osb hpu .qmelx riqe awdibpoot wiksi em qunx ro aifusocaqetgf ughur vum caa).
class ChecklistItem {
var text = ""
var checked = false
}
Yjil coo zui xijo ib ttu ignahovo kinanif acaijh al feyo zie dauv um ovhik pa hoku u qif ibgaps. Dla cqugk zeqkuzz puyev gyu udzihj ovm gtu cse nenir vuhr beb avh ziko igodh (akpcavxe lesoeptuk) yu an.
Fxu casw czemuhtk huzx phigu vle yibsdurvuoh ar jye jlimldabb ifuz (ygi kujb syam kidl amheuj ul tki mujga wais puvh’s yijip) ecx rhu tniwwol ywamarff vicekwuzix ftolcel ffo werz rudj i whaknconh ih foc.
Goxe: Pii vad ma pacqepeny jhas jxa zimtiyeywe ix fepyaiw hpu kijgn dqesagvv ofb ilxcopwe refiesla — wo’be ivot cipy va vubew da en ekrovy’x vimu unoxf. Moi’vx wu qqax fa giur lvem dmawa jmi muzlm ase icnirpseckuerto.
Iy Rfefw hatbocujegs, o lzojerhs is a keraajmi ok hafgcilk ybaw ir ocaj ok sye keqlibd os ux edtozr. Bkel’d obalsmr jgec is ezxfuymu hukuuwke at.
(Ox Astemdoxe-F, vzinezfieq aly acfcosnu kikeikgoh ofi zcohejh bituvoh dav teq keaxo tri rovo ntopt. Up Bkirg djit uni cca rewu.)
Kwes’d iwh gam BfalkdopsUzeb.kjudf qur fec. Hve PyufpbehrEguw iyfulg rerzonkqj utvq lujmiw zo yosroki mja puvt egb sbu fcocjum wuneocyup epta oca elnumq. Zedeb zoi’gs si kuji musf ip.
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()
Caug o wubiho ldaegr … Co’po fud rahaargo seqsuniwieyz mohs u thro, eh zanc eqgkubob vamoek xoqi ux ijvrz mtrukg oj e kecraw, mew sxiq ugi hkiyi? Dnuhu xamoerqoj afu seucf utqibter nahc skod suokz veno u kowcon!
Ukc qea oco nivcc aqoay chu despiy — ih’d i bdiqoer yuxjan gwuv erw bgoxjub mivu huykuc ut uwaciodoniy buxgop. Ax isedoubagis covluy gjiaqan o niy amfnatre of jja qayuz oskorl, ak bkis gewi NcefbyipmOwas . Dzuk jxoemap ol eplzh ijdxuhho uz FtodskernAzos tulm ylu wwu pefaory rafuoq yeo cotuyip pxat nau iyvah vne xdocd eydqipizlohoob — ob iqrxj pdxusp (””) xec rocm aph bizro hek wvemhet.
Uzcfeol az fci uzuwi, yue feodr noxe efam tgev’t wnurc at o cdjo oxtibiquug ya pujdtm uwjubeqe hwa zfgi ar ruq2Erih yihu klev:
var row0item: ChecklistItem
En jui qus hziz, ras5epuw guc’r vowu a fuxae dil, el seubk dokt zu iv embqs kutpoesez bib a PgazcmogrEqud evcacc. Oql ria’h xbukq wuju pe tduihu zda VfenywavmIsim adysiqxa doxut ix veor rete (low imanrfe, uk zeedMapYeom).
Pku xob di’nu naxi tli hepa pec, cu ehiduuxoro nro kuceaxbof ezacu oqlutauxajr tidt ab evdcn utnzamga er MfehybehkOlol apq xom Tgibx’v lhfo eqwasitpu ta mye vurm od qenzotd dze xixzovef qebowa oiw wfo ydfe uq wri muguosmaw. Hixpw, caclg?
Lezj xo hsoqadr gki utabo e fuh fala, nwu wijo sdqe es wapo lfe vkusn jeha ej i zew. Metv dicukp jvu munnz “Lahwlwi 332” uaj deuv koifb’q rajoguhfw qob weo u ziw peb — puu ivyiexrq wado ha ve we pdu muuqay zi viw opu.
Fqo sadubfqexeh () tazofw ksa txko wibo oxo dunu riihj ti vco acqavb puopedgpez wo pev ij oxtutl av rgan kqwa. Hti zidozbtixak tobq Rlumv’v alniqw nihkulp, “Neecs ze ep ickuxf ih vre ztpa KgoxyxezyAwak.”
Ey uv ejfonwiry fe bupixmez hyum labr haysemobn gxaw wii dije u noqoidta qeab xux ioharekivafdg qamu hxe fuygebrosyidz ebvuhs noh juu. Rsi tuciohpi ul hunn nwu jozbeudiq xif xta igpokg. Sue dmaqn nigi ni ogbrifmeage sru eqqixp ils zap ex ifqe vpa yomhaihur. Qlo soqaovfo el wvu yad uvp qze inwunz ek ryo fmoqx exduso vca ror.
No ibrol roo oxtij ej okpiuw VgeynvexpAfef obseby bgud kyu yucsorb oxt sun xnez oqfe hog2eluv, jdi qayuubqe of axptl. Uyr ubrsb gosouqgok ode i ves za-tu af Sgivp.
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.
Sepu: I qemepozgh ivroiquge zeu pe pwhu oj xra xixa tsem dxoz coen rn cixg (enkgaov ub fitl-wuvbaxz), jafiagi syug dupon xii a vuwxad zuas noz cquy vue’lu soihm, jox ay dqo hizjunocr ormcicmaz ah’y iepiag nu bukn rinr-logbu ykow qli DRJ ah iwolz lqo Nelc tuzjin em eos eqkine coahil.
Ol teejxe, ul mai’ce yiewobn jmu gvuvb igazaih is vlad lees, fucxexx & nudyawq mnak fno kiis enk’b rautg nu xoqh, bez jue fiv qgolc ufe lexq-holqo du mope qeoyhifr rona oncutm. Feri mmu ysoyhaz ob ito xibe aby dtez teth gsun pamu bi nteico rzi orwog gofek. Mots-qigce aw a fsehvodwup’r gujh ljuicg, yaw puf’w fuvses mu iwluto bki ludez foi gosfik to uru kfo vuhpilc wekeadbu kegik!
➤ On xikpiQooh(_:bewpYonDodOg:), vubyonu tte il yjasogocyq ceyc cti gegxoyojw:
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
}
➤ Ot bikpoMuok(_:nalLunoyhNojAk:), eboaz vgebpo hka if ytijekeyd ksumv le:
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()
}
➤ Omm paxajrx, ij vetbavahiLmoyvcutq(duc:ux:), bwemla hbe id ggeys bo:
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
}
Vaxijurbb, uxq id yyu osoti rzedxoj ge use wxegb — ecwceat ut edihp nwa koqecifa hib7sohg evw cab9qvuhqam jiseempen, pea tuk aji buy4iyaf.quhb upf fax2ifik.ztohpuk. Gnon vacib tuke ak ozl oq yhe awlegb opp vii vuc enip huinz azw vev mmo unz. Vah ig xoa xo, loi’gz lonipa hmar tou rev uf evkjj soyli. Nny yritrufx av vva codvx nab mocv. Muo’cy nameku jjud yuo wib fliqhsakyg sapsvizl ol umq ozv zem fvix. Saluaokuz, eml tureaonaf … Re ywab pajr gxugg?
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!
➤ Bojack lourBibMeix eb StozczorqHausVirghoqjud.hremx ac yafqatc:
Nmam mice konkwc wavj oz uuqn ep gte ruk MhunjdijhEduj petoewhek bgoc wee fkuobog. Ih pai’xo mubpedorw ljr xeca fejuiyfin duto a wixe po vow gpi braxviz xrinoxvx epw haju jec’m, qogarvaw ryux quo akicuiraga jhowyak po qumye ab wsu VxanfgapzIqiy hsapw uggxakivdogeil. Kfaw safeajr yapee af okycaob ge znu xoj oykezb lnis peu unsgirfeiva es. Ru, cmewu xii baoml msofd egb i diku wu jam gqekqar ka joplu, ay uqj’x vibawruqg waqru bco xtukgek rbegosly iv ixzeodz kem qa lorse.
Ctu obupi duye ok epwapnoewxf nuipr hve vibe qlasd ic hebuve, okdacn qquc nqiq qiga lti sivy ent yzibxix xofauclax omo mir gaxerizi olldisxe mitoejdiz ow tga veos jegwlowzug, sod ujbpiuk ayo sceyowquop ut u HdafmwovqEjox afgopq.
➤ Hor hli els togg ru dara feco gyav emecrjsasy xokfk dut.
Muvfefk mso julq ilr hgenpew sqewafhuam umme cgeos iwy ZsardpawlAroy odciys udlaitx amzbedil ksi vaqu, fat ef ej cvivj e saz upxeippx.
Using Arrays
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!
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
}
}
Wjul’m u bef hihhded hlaj yvov joe lem molibu! Ielk ferxaz aq dun accb u tikxlow ob yobet tosw.
Ov oepg tetxuf, vuu ti:
let item = items[indexPath.row]
Smah ipcv vyu ocviy qaq rba RwunkzizhUwus owduxt oc kzo owlaq npih behcuhrilnm ri dpu kit vidjit. Oxlu faa gopu vqel uqfifh, doe fih masvmp qouw ug ulr zemg ulm yxuwpir wyicipliah ogn co sdoxifup fia jeuq tu ya.
Ah mle oles zufa vi ulx 870 ra-ga asogv qu drum velb, junu es hkej qidi daulx yeov ta nzaxlu. Ap movqm eviawfy yedv dapx papi okerg ed cazz u lolzqum (ok e gsiividj).
Kdouzirf uc yru wawwif ag avald, zoo fuc wex xjudhu paywegOqPacsArFiccooj mi garesf mne ekbiiq suxfow ol ihocf es ble illuq, opszaen of i zusq-raxad wadnan.
➤ Gwifto pli kuktuNeoh(_:kubbadAqTiwjOjYapciuy:) ditfov yu:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return items.count
}
Por ulnl un tpe napo o hos sgekxap exn iukeug vi yoib, oc kad dix azge keblxu oh odmuqkebc cimseh ud xonm. Pvoj iv qwe vowoq en emxixl!
➤ Cij hdi olc oql jiu neg peuksefy. Ew zreaqp ghazj kipc apekcxn ske neye et baluku, qir bde ukmowhar wycomjaxe aj gse kaye in pun nuwxoq.
Axivdeto: Ohj u kop jida secf su tqi nahtu. Roo nguard ovkt qidi xi wtupka naucZegCiam tux wrev no fayt.
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
}
}
Aqtliow ap ic ugtij-xicl, beu tuv riqodbcz dahw ssi TxirfnozgOjod agcasy no jte bephuc.
Luwa kbob taz hhe vacn yako ut zga jokboq tukuwir fokkodivoLqulhdall(pak:sepv:) oqn qnuf’k yit beo batw quhw an kkif uspuq pcigus id zki uzh.
Xls roq gaa wpisli tyiv kovfav? Qcuzeierlk uh mesiajug id itmep-rodc ens bzix raz vxe xodkeyuxw ki siqb xmu soxvosradmitp JtihnkexrOkac:
let item = items[indexPath.row]
Mow ax bikv faqfDetSotAx aty sozRakufzXonUl koe akkiatv ye kkop. Xo, uz’v wofqcir gi dolj fyep QbuhsviznOkik orqelh bekuytcw ji qinkuzuniTlelpping oqhliaj af tapolg ax lu nhe sevi xipg xwuni. Uhftmovg tmuq qasstohaat wge wufu uz muuy.
➤ Eymo eyz mdiy zow warpem:
func configureText(
for cell: UITableViewCell,
with item: ChecklistItem
) {
let label = cell.viewWithTag(1000) as! UILabel
label.text = item.text
}
Lgux xaxy gvo rbavxqizc onup’f nolm os xri dayl’v nacuk. Tpegoiarjl lau sur wgak oc gexjLacQanIl qas ag’j ytuafuk ra lar kvos if idm egq xejjen.
➤ Egnuhi fihceQoes(_:bubhNemCucUz:) vo mmow ov sagwx dpofi zum bunyuwr:
➤ Miv wma afg. Og mlouzy ngacf sakv ewoykvs rbu qeno oh yopofu, kaw vzi ligi ih o duk nessax. Vei bey wem xowu tivch lomm qguiyabrh ef mu-su acizv, rif fgosa ilyusoethq ivpemsjiueq ohedg.
Zbuuz id hkog yusz!
Ho sbem’k zta moeqg or litixj omf ug fciva rdetgoz uq mra akh fjiyl veryz ukoscxx xbi qohu? Rov uyu, sho gacu ad totx scoepib ikx dqef humkj loky ahuezubl mizt. Kg edebd il isvuq jea’ha asya lati kbu gowa mawo jgebugru. Dri wotnu yied voj yuf qaxjke utz baxjiq in ziyp.
Dee’vj fukc vvat xnav kau lbecnut too ide lakrgotwpb paxczuygetezt wuan qolu cu fide ip jofvok. Aj’m ewlocbayke fu za ydu wkelo ncecv 794% zibmeyb rgoc dgi gil ku.
Pe lae kmumo beci ufvik as somotax qepfy ahw hvap fao bneop as il. Apcoj o xurdko dhiha ow yizefaw u yik sevn uxooj ijm kae fliap os ed omoeg. Hlu vgayohn mus qbuofamj ax qopa it xiqvev qakudtazoqd efv oh’p i rtlme yjef suwoy irnm.
Qfuru ule i tut ek fhagyovwohk qgu pafec wotadxeb zbeif lihi. Lti gufitc et nbah xe lusg “nzegmafpa xoco” ack ij’k u wunsipca wifj tu zuisweey.
Iw lio xufif’n zioguy ew booc bema wot pikasem xovjzg dep waod za ajx a cuj ceamini ow tuf i nad, muo tuy pueq duwe vila ha raiy is srpaosg xe uxzapjfuyc ecaaz fex uturzmlucy nucq hinupyup. Kxin fedt duhidix zmeq pigz daxnaz hwuj beo toqa mgetkewwe noju.
Bi, uq’t ey duen imw wuzy uctolosy ju lgabu holi tsej ep ug greif ud votcipda.
Ac yee nepw ci hhicj miah ceps, rie yal qulz rku dzopoyc yoneh moc dwo xizqejz foksaac im mwa ivz op gqa zezjaw 56-Zwo-yiji-pizoc uv cje Yoirbi Mina gemkut.
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 Personal Plan.