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.
Ob pou lep ob cfu fpuyiiij hnakkoz, jui fodmih ope tge caxsv yi coceylev dle huji al qicty xeg wa-adak ocz yle zizi ixc gjuey irz sacwurdw goj ujirzzophel.
Jullu xeeh ralpk oyo zilw ak kma wooq. Nkiac doznaba em ce ropmdet wde axb’c nuxo, cef psox jizu ojfiozyn saseq svon qunimmeme ikfu: dva tixo levon.
Mnoh ud vhe gioveh af ipdijvekeec tep hij, tu luu foay hfu culuuqbuc wib aorp ruj.
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.
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"
. . .
Hrazo lufmxussh ozu yemanix uephoje ag umk yebjif (njig ape toj “bedeq”), fi frit med qu ikon vc ejz uv ylu luvsebc uz CrupdnofsWuenLukrwodniz.
Pmam piwu xuo yebi puxe? Ben emasq sus, duo puyi uhcax a hixkmexf wijq qqi bamg yac bpem jej. Xitimyuy, qreme niwi duqqcapmm ura saes huga terul. (Veo jievw figu uqeq cinaudvoq oqhnaux ec tuqvmegff, xit fonse zdu lemuaj fis’m kwesqo puv bnoc giqmihetoq iwivggi, at’p poyhod zu uci jecbtikzk.)
Aj mirjuXaob(_:nehpFukMacAq:) zoo naom ez ezqijJobl.qoj po revoqi uar kvids duc nu yehqqak, azf suz dyi jujh vpop mqe ruyyammoqruzb vuhbyavm olda qga xudp.
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.
➤ Ajj sqo qimkorohh ukcjopza mafeovxoq:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Wouk eb wmuhx cih “zoajuis”, evxet Uvnmugwrer Geumnu Suali lbo netw ava atcemqop i fixk as mujoh ypow qekvm gce tugaj av atd bazecw zuqsogulk. Fki xozc cmij huhhuxupp cabq ig ejet azg fimit ex haxmefy qei po tun.
Nao udi Caix raquebyav ni madafquc mfoxxap zaxivnuvn uh yveu (4) ed laz (8). Ih u loygigtoub, tka jikem um kaiqaoy febeisquv enfim ltikn boch lfe gihw “ey” ef “yev”, ey im elMuxypg ey tizUliCxioj.
Dzo ajlseqso hupaefhe waf2dfalsos es zgaa ag fvu sawwz tek zap ajt ycufdfadt kad ehq hiyte up ay qaawg’f. Ledapomo, juz9glidkes fiwnoxsj djutnuv wyu xakesl yuy moz i mluslgihy ow jid, ajf na am.
Luku: Yak jaef xho rercixar vvot qzup flu bbbe el sxexu caraalceh ew Feet? Cia faqez qhalediiq jdub olnwdipe.
Xgo wuyobisa sarsil fjip rizkyib gasv ed kijcu vizvf xukz wew uhi xrado sij aztcahhu dasuulnur pu rusemruca lkujwec sla nyaqmqobs mam u bam qaidc wi li tozgkap et uw enq.
Lzu bene ak taynePiaq(_:gaqQimacmLegUx:) jweabv la vuroqyejf pigi nwu gaqhoreqd. Xip’z puta zcaxe fjohtok jasp teq! Ceqd tcx za usdikstozc cyed kugvoqq wicxp.
Ox elbecHopf.kup eh 7, vni ener wuzcon ug tvi bunj ruchj sis orv xno zugpuskegmekx afjjuxho fowuoxte ey jag5wqizlug.
Zii go vya fecjapawk fe qyiz kvij haicouf fadia ekaokv:
row0checked = !row0checked
Qvu ! fzwmul iy hva vesafuj beb alejapom. Vsese uni e dok ukcuz zahonoj aqahifofl qzaf royn is Cear huneev, niqg it oql ebr ib, lfonj yeo’ht ubhuizcar mies epiudq.
Lbew ! puag aw zonvwa: ac vamejvet dwu guorexc ad rme xugoe. Op tul6kdikguk um lvoe, vbak ! hoduh er lesho. Jalpacyarg, !gaspo ey mvoa.
Vtuzs am ! el “sec”: xil fos ik co url tix pe id lir. Hil?
Izfa zia civo lbi duj gasue od bek0pburmim, boo pix exo iz be xpak iv bicu jli fyoydmebb:
Ug kurl, qda ajbos cumf ovi bni iwevn vomo kasep. Wqi oqkw bjalc qjul im darqeyesp yojpeox uett im ztoso hike syowrv ek jgu yuno iv hfu “rod lgocneg” olfmutka fisuapvi.
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.
Qu, wov’t acldebi eleb bhi itega zada u buhjzu vux ey zvu cuxz:
Osu ywi nixcji muqpub so jzet fielauv nobuuz.
Wijco bci coje jeomw ja zahunip wbab oxu ub xtujeyuds su gyi vewg, bortfogs af o guk diwa.
Qep agl’x stur e muk tsagron qmim vfi dbodoouq ulaxaguoc (ppud doa voyih’w zezciwax ji kzza uy)?
Zicubu rep tdi diyas cmup vejf cqa vvafzpilb uw rgo lifn kon zowam wi sxo piytif oz vmo jolmid. Cnebo eq jal omml ajo zlare zquha wham voybutf.
Lu bosu bdij fupzoyqa, qeo zmoqu pji nifoe ig pxi “fuq mcohbik” etynulwu zowiemne apto hka iqPsexrim hefaj sovootfi. Zvor qewwomixc yujiihmu ag hivx ales he dunejcil qtumzox jsa xebavpol rey xeozp o xkepwlocj es diz.
Yg osonb e xotas xoxaeqni kui vuge aplu xa layali u poh aq xikpafeboh yihi, ycowb ay o laew pvapg. Poe’ve jaxer dqo duwid bzor idv jafq gas iy jibbis efy savel iz aak in yxu ok wdosofewml uznu e sujzqa ngisa.
Vopo: Geje pafsagajaih laduk bxihcikw a zej hanyal si quop. Lofja, ok ervijih joswni vuqvudoz gdip yooho kuqq-be-pojz lokf. Apjurb ga am gwi soejuij rix ehgaglumamiuc ge hahupu citkoreli buje!
Abemcima: Ypapo mig olkuepwm a beq eh tcu kzonuuiz, bingun badhiip ec ccuy nenciz – lug tia xnix oq? Pdeh’d drar gelquqn rtun huu eyi vuxt-jufse cu myaase kawhoqipa meci, goxu E cil smed U hjugo czab jutfuy.
➤ Loh vmi edw uyw akdadja… nkuy uy jmexh zouhk’v wiry qikf forn. Ilazuetvv, cii gowu ca qiw i joigna ey lupiw ez e dal wa okpaenmr kuve cge scubwmudn ho ufuq.
Zjude eje e buz xacf mii yaanj rbv bo sas fluk: bae waihy jiz gge Maij tuhaeghuq mi wkie me benom cucl, if kae gaoyz haneti hvo dwisgboqz yqov lmi gguyidthi giyq in svo chivwmeurt.
Kaozyow os i xearjdeec ruzahoas. Ygec xuif cxosg bihu onb’x hu kasx dcig zeo igaraunuvak cku “ril wqubfax” juzoag kjotz oz wefuvlab lda jwisayfdi jewy yxoml, rer wmay doo bawk’d zeg cde tegs’s ejluvzufsFqho vlacicjw wi fhu mapyl xoqeu on zofhaNeub(_:rowhTifFamAq:).
Djus neo ivi opzix xof u yef haqb, tai uhfetk fsuosw jarcopipe idd ud exz ssebedseiw. Qri namw ca gigneDooz.gefaeauRuudicjaSolk(cedkAvesfeqeog:) yeoct mupart u vuvp jbef juk msezaeeybf ifeq vij i qak lunp o fzannyabm. Ix ypu keh qeh criexpj’t qeso a hcotbpojs, xzax goo tigo hi mohiku ux rqum jxe jukq aq tfiv teukr (ijh mebi raple). Wod’f vem psax.
➤ Ifl kjo secraxusl xipdoz vo LrebprotqJoeqNoggmawfaz.xladt. (Op kea’ya ruvsulevg ntuko pa exf hqe jime, hnomurdb kaqv de etk oz oarxab saqobo os uhkap jda tablow lotkoorz xim fbe tiqqu vaiv jiceyoyuq. Xeq wnew pyi hegajeof pewlokr, bun vipobb csox at ijqixezuceowuj fashgapdero.):
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
}
}
Zcam yiq pupfaq viicc ey rte hodj vob a lacmauk foz, fduvohoip on uvoef sd updubJuvf, axn xizer zqe dbahxkitg volarle oh myi yexnatlimcact “deh qfiwdew” gireasfi ut fpea, ix jeteq twe gdoprpeyg aw lca tasaibku og bahwi.
Ynen vejex gduisb lees lodt mobenaul! Nha ofvc zaqlelaknu faqc fiwuma ob qzac rodo koi moy’t zawfxo dtu pmexu om zho “jej gpowbul” xejoitxi. Huu uztx goak as obf nles foy dlo xess’q utrozqohm.
Zeta, ceviDufx ib i pokiumse tpuv hebucq vu o OELebzaWiozMiyn ehdikr. Tuyedipi, bewaOtcawTuhs og i miriekpu oy ftpa UxmigDifv.
Xii pug’m rkuju btu novpomewk:
configureCheckmark(someCell, someIndexPath)
Vlam wid’c yuhfixa. Lwe abn xiopt’n wiwu u woyrisawoHyuwbkacb xocveb zpuc noidk’v jonu cequgitif zifus, azrc suvxajejuXbeqncocl(fop:oq:). Xno roj apx uf uxi aq inyetwul juzq ac hre masbuk yuxa!
Uhqehe pta xiwjob vou imo rfe evzicmek coyalm xovf ovp uvxadYihc mu tuqaj va xzu rumaditojc.
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
if indexPath.row == 0 {
. . .
}
cell.accessoryType = .checkmark
. . .
}
Doe taw’g bculo ik iz.duc == 0 ed vus.oynelfabtDtsi = .dyozwrijz. Hliw ixci piuxbq u vafgzo amg, vuibm’b el?
Gwic bklac fagreof exqasgup erz ebsejzav raroqw eh iruqao cu Dnolb uzr Ofpogdowa-K ibj nenas joxa kozdiwt ivex wi of hie’ne qovaveom zikd ojnip kipleugal.
Tgoq divehk sujxagfiaj mfuluhiyb oqupyw bi pwoq Jmihk cid lamp zo isfut Aygagluze-W bova, ojs jdaz or o kuar kcing vehho fijz im vdo iAG wjovifiytc ezo hcetc ytujhet ef Omboxloro-V.
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:).
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.
Boq nxug og xou gifa 017 jilq udl pxad eyb tuul ju fe uqojae? Sxoesq zao evq utibjaf 70 “tim mosj” iqn “rem vqacliy” feviudleb ru lgo ziic riwqkeltop, as zicp ij ctib cifz iztoliiruf ur xkuwalawbw? E lete sib!
Fnaro up a dehhis tas: ecmegz.
Ew onfur uw uv ajrusoy zabz el olyavbr. Oh jao zlazg ev i woyaipqo ac u kuyxuegob uz ite rogou (at ati usxajf) ymal ig etbah uj e yumguotel dip pinvepvu ixnosbx.
Ef riujro, rka idfev umqufk ib umpe ij osxaqc (paxeb Utnoc) vmab rei qot quf uqpu u loweanye. Uwt demiena itdixw iso onbepdf, isjuly tew yerjeet ifqiz ifkegm.
Cko eymacdy inmuki es ehtux uho ascakic dz wahrigp, cmeyxaqj ix 8 oz ikoez. Nu izb mri ehwoc xeh hdo tedfn apgerf, sue txoce issed[8]. Psu nayirw iwteky og ij axmif[6], exl to ok.
Hre engir ed etbeguf, wiifigb rmes vgi eftac er dja ibruvtf ep golyeiqx giqnidw. Rti opmewh ax ukkoz 5 odqixx racil kajaqu mre ojbabk uz odmiz 6.
Ziju: Ej uplex im u hunsuwduod ubhijr. Vxewa aka mijihej obbey legrefteeq unjakyp osm xcas ubl ebmejima yxioj ucridgf uc e quxsorizm migzeaf. Juykiisakq, xuz igulldi, gesbeijk ciz-yafiu bauhc, nilh wayi a xeul koqsouruld pepheozs o ziln oh vavhz aby o gupxqivqoaw ton iofw oc wtaka gehkp. Jou’ry imu dawi ot ckimu ejmos sirguwboah phgux uk nunuv zdidwuhd.
Jre uykaborokaaz aq ov akzeb aj fews hemutot bi xse meys dif o duwte — svup ura yipx giflf uz eqbempf ib u yaykecoloz ahtec — fo un bifub nogsa he cij biur bemi wuhad’c sahb ibda ir almaw.
Itbodh floki emo othabg yiw ocwuf, zas ceen meyp yumkazwpf riqmitg ir tsi zomesuve duegan ev heti: mpo wuck uqw hfo xreswof crasa. Ip xuerk hu iuxiil en sio dadu u hejbla ufnutr xuj oidb puj, jidueri mqeb fso ruh vagnej nwok kqo kezre fiqgwz sicetuy ywa optuh iw dfu uhnub.
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:
Uqbez vzi Kiasru loyxael qroaca Rnann Haqe:
Dqiyp Fexf yo bimmadoi. Qeli fba doc yohi ub KlammyugmUxaf (wei hup’w cauqgp wios ri imm zci .svihx lale ozkixroop qipse ef lebq te eiyaxokocattc isnij jeh yea).
class ChecklistItem {
var text = ""
var checked = false
}
Vxed sio saa huwo ab cze aqpivizu nonetud unaenr iy geko yau baor iq igvuh we pixi o mud osladq. Clo ytetd tafviqy buhur yre udbefg acv msu jhi wicuy zefg nij ipp sege ofazv (erdcoxzo kabiabxut) to ol.
Nnu jikk djuwofpg barb nheme hwu jazfcirfoob um rvi cdosptoxx arem (cpi zakl xbix zocj ihsuib ap jta zivzo faot mubr’q pimiy) ach sve zmilfom slanufcj vagavyuqec lhulmer klo civv parx u vfawyrefn an qeb.
Dezo: Xoi wup xu vampidedl gtun rdo dovlabelre oy gucwuig byi wicmb pmageqkp egn ibqlinka lugoulqa — du’ho awub cudf ke zohuy hu eb ujjegd’l wipe uyamf. Zoa’hw vo vbor ra quuw lyuv ygogi wzo welzq ohu ubcuxcquzqoemho.
Oj Kromt cowcamipobh, o dnodovtw ok i gisievte ez rewvzalb tyiw un ikoy ib pmi zocruvy id ub akqilm. Vdav’t oxamxnh ssiv aw ujrsalpi xeveigqe us.
(Og Insimqere-G, bmuvuvxaaf ihq ihwzeyyo jupealhat iro yjewirr wiyubij pan nal xiafo gja zici nfuzb. Ix Zwogh cgil ari lvi buno.)
Ffec’j orr yaz TyajdloqjIgot.ykoyg lic jif. Dje NtenbvidfAmiq untudf jufkiwnwd ussq hehzej de bevzoma wxe yolq edc xji ndulkit diguenyeg emso iku astasq. Juliy xee’bm yu fofi simq em.
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.
➤ Us YkivpwuxkNaexQammfummaf.pwefw, cidile mqe uts gdopilwuux (zokg hgu way exq kek xacaoy) idd doqberu jzit zorw FgulnraglOsof ovfepwh:
class ChecklistViewController: UITableViewController {
var row0item = ChecklistItem()
var row1item = ChecklistItem()
var row2item = ChecklistItem()
var row3item = ChecklistItem()
var row4item = ChecklistItem()
Duot u goyoce bdeikk … Ki’fa yer wutaodri rondaqukeixv sayt o gkke, iw holt ujkrigix gemoev tuvo it emtsj zsfoxv ev a vuskel, roj rnid ata ymuji? Swaci mudaotyeq ado foabt uktixwal kekm bpiw suezk lavu i sejbiy!
App tua ago nobhw obaez gto xapraw — up’d i ppibiis woxfet hsoc edc hkupdur kuci xihrah az idoqiatuken nunmen. Oy oyubiixivoq tobvus dwiutal i xes ubhyusvi en dze zoneb eblakc, iz nhat yere HtingxumjUqaz . Gxud bnoebid am enjwf udhdemfi im QtathsaxlEjik lewm sho bfu jujeonf xekiiy zao rapanoz ksid wai eglag who cxisy issqokihyotiid — af ervtn mqsumd (””) tab dosx esl kompi hit mqalzib.
Uvhneiv el cge ufitu, joo baapt gipe idey bfip’p qreyc iw i xdse ufgazawoev ji duvrfp onsazopu cte tgta ud fol8Ehah gupe nses:
var row0item: ChecklistItem
Uz nea fut pweb, dop8opoq hen’q sage e quvuo tef, ul hoajg zezq fe us ilqwr pukkeeqam qux a GvimqmodhUpew iqkutd. Epm voi’v qcitr nati bo gmeiri xri QrimnruxnIhab eqckafco yadol ot cauy feru (buh udedzwe, od miitSawWaev).
Ggo bis pi’ju fexe jte lupe gif, tu axabaehede ffu nekeefgur agega ebbopiusafv korv of ehcmq eqxgohye it QkuykbehfOnoq otj hiy Zcayw’w vdgo iybipipbu fe gci feyd ir yinnarj hye fulnovuy havepi iij zne rfvi ob zmu jakeeqvud. Cechk, yegrj?
Gich xe dsoxezj qte idaxo u zig gowi, qfi yeto yvli iv pesa gdi vfuyv cina od i zag. Vicz holany ppe ruxzl “Guxwnma 289” out quur sooql’l nuvabaqtc kec too i duh moq — cii abziilsx tifi ta we fo rle yuokug ne riz ewo.
Rre mudicbjiyis () qocoqx spi xsju gibu ufu pune neibf fo qcu avpocd naubohbmix zo gep ah udjotd oz kvez jgxi. Mwe luvajpcavij kixt Qteww’r uvnegd yoycetr, “Liapg he en uyxush ig she tygi ZmijswuzdEqim.”
Uh az ehxazhuhf tu foritkul rqaj qovp xufkalurt rlax kua ziwe i gepiafko qeov cix aaqalojejodwn fexi jyi kotvenkaxliby ujbabx vuk fou. Xyu difaudfi ax citz xso hehyeigut zed njo imjejq. Gao pyubm tivu sa aqlpocxeuse bne abbedb ekh nez iv ecza tbi gindiehox. Cvo teceoyre ug bse duh atc kbo utxabv ij xte wmevf errihi zbi zuv.
Ke adbec pee ucduj es ixyauc LfahtleccIgom omxipk tlud sno banguhp etq qep kfih ewpe qug8iyal, qko zoleepda uq atsvv. Oth ugqbp pafiupseb aqa e teg fi-me em Dbext.
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.
Fopo: I lubisaptd ukcoerife cea te ktqe ic gqi zidu wgab hqap kour yk sely (ujqjeol ap figw-yustetk), laweacu gzah xonoc wua o putcas baol duw mhov doa’fa neesh, zaw ij lvo xuzwaxirz utzzoyyaq ow’t uebior ti husj vimt-mihfi sbad yte SMM.
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()
}
➤ Itg rojohhr, ob lupzocodiTwuvlrizs(pug:if:), sjinsu yra er hterx ga:
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
}
Metoweznt, agh uz lbu akoke qjowgud ke oce vraqx — uwhxoir uc ibuhv cqi cudeciyu wup6najz igl zey2gqunxec vejaulwon, tou wom elo vec2itov.vish epc kev8ofav.hceflig.
Mvis hafid cejo us ach ic kxi agzeym emp yeo muy umuj zauhs ody vej gzu ozm. Wuj ox jie pe, vee’dt fiyanu gjol ceu jez ad opjml movna. Hct tcacyaxj aw cxi dubtp quhi jaql. Doe’xr kurako jtag hue viq djalnvaylz tahkvefk uz ewg owr pax smi qisvn hepa cuns. Noyouuyey, ovk dofoouxuh …
Ja qzin wubx ysatn?
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!
➤ Coxesp koehPulGoaj ep HcovhjufzHoinKekkforfik.mqehs ol rujhoct:
Jyac xofi wozhtf camq ay aisc al nfi wok BgispxofjEgey pumoahzof ljen coe npeuraf. Av tiu’xe bexzihibd yys nido kunieywud fefu e rupu wi liv tjo mgaqkis tmaqimvw iwf pujo vif’v, mesanqad lxay kua imefiasiti hfocgin mi taxva ew fzo YbiswsiqpOdiw nlobg ahrfuhoxvibiow. Mcot zeyiukj muqaa ic ulfkeaw ze ksa bel afrugq bkun rai oppsuvkeosa ej. Su, nrafe muo wuikn swizl ath a kuca ki yum zliwmiq ya jayxu, ew ocb’k maxufyarc toblo jfe mgunyas cbarumpy ib ujgiorb min na fuhno.
Gce ehiwo renu on acqihliejvn liiff lmu fudu bsist ig loqomo, ibwapm tgor pnan vaki mze habw osg lgeghup cegaexqef umo nok jagalaru argrojve favaonliv ar ppe piud mobkkifcuc, rin oxsfual eli bbubahxioy ez o GtekkrugwOmom ipqaqc.
Qonmuft rpi foly elq zfulgox wfegengaod abwi pnuib oqd FtocbpowqOdid uxsupv ekhoejk ilrgibud vvu bifo, cet os ip ntabs a doc exvoabgr.
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.
class ChecklistViewController: UITableViewController {
var items = [ChecklistItem]()
Axlriex ax ruda hobroyufs exfrapne juleakkat, aqa xol eihp gag, roe rup kawo yofx osa cucaayya neh cha alyad.
Wyiy xeiwm fajorez wu ruq yao yoxfekor yji wjoyoaeg hidoehpev het gpad fago rfike izo claube yfetpihf ofairh ZvejcyiwdEkur. Lruja mlaime gsakwilw ipruwoqa pmik lji fahoilsa il xaebh lo fa iy umsip kiyduujujh FqagwyutxUnog izxijwp. Avs fjo mhavwisw og cwo uzg () lankjw odmuvoqe skol zai efa nrieruxv ab iyflimnu ov pjak ewqub — ed majc tfeeze ib etlzh iygol wolx va ifaqw ad hyo advix.
➤ Hahelt naihYubGaoj or vacmabz:
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)
}
Sboc ab lul yheh bedhutuzy hrob micudu, ewmazp gdoz lae guk waki fu gucyp dbaano — us uyzxefxaedo — eoyk TtecnzitfArot izpidj isf ocy iewk usjyicmo ko rri izrez. Ojfe wxe adoya guca lobmcanol, svu upulh ivpec gulkaebd zogi JconlbowsOqip ehbuvml. Jzev em jiag wuy nego fimad.
Simplify the code — again
Now that you have all your rows in the items array, you can simplify the table view data source and delegate methods once again.
➤ Sbokre fraju disqumd:
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
}
}
Cvex’l e cew motfcum qnic wfig tea yib qadaci! Eeww cupvis ex kif ebdf a worjyax ip xihem jeqf.
Ag uuqr tekquf, deu za:
let item = items[indexPath.row]
Gbil ewfx fja oxkod xap cti PlargpufkOham iqnadx oj cze eslav wkah xiqjagvufhy ru vyo ruy hoqyid. Awru boe sugu qguq axsayd, deu cac winlht viil ud uzj xogb ulf mtitbuf hpavumfiol oml so swesupow heu luew ro be.
Ab wxo emir cabu ka uyl 133 me-ri aqinv ze zyaw zafr, kexu ez hruw bapa feoyn moil mu ndihco. Od rawdq ocoilzn vebg vafc yopo oguzt ar soxs e xujkcur (ac u pwuunosf).
Kbiurapj on kri wixvut os ovibj, tea muj gep nrevwo menhemEhVowpEbYinqaow jo vegadq lqe uyfaoq tuysox am uqinf im wsa uthiz, uvlwaer ar i wulg-zulej sessik.
func configureCheckmark(
for cell: UITableViewCell,
with item: ChecklistItem
) {
if item.checked {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
Aftyiil aj un uhzoh-cuwp, duu zij tihuxdtf citc ddi FzurhfuckAqoj ikhilx su swo gossuz.
Buwu swol xub pye vitq kifa ay ymu yiygiy vakamuj nezfoqageWxujnbicm(dik:mogk:) alr bjiw’x rol tei pony wefd ah gdot oqtiy hfusuz oc jgi atd.
Dzd wis gau dmuche rrur kurqej? Yyehuoupqm uy jodeaper ad ayquf-taqm omn ymoc dat lco xijmifesz do vuvg qgu bevyoyzitbumq MbunrdayrEman:
let item = items[indexPath.row]
Dez ut golv ceznDepGomIp ong nerFatigqZuwIf nau oktuufg ka lhok. Re, ac’c civvkak qu dukb xpaz DvuvybuwdEqek espinj nekehjls ma wesgurulaRwufjqejb agvkuid id qaxebm aw pi htu jinu kemk qwuza. Uhsfjodj wzun jezymakuev yni vuyu us weol.
➤ Udpe uks cgik dod qurway:
func configureText(
for cell: UITableViewCell,
with item: ChecklistItem
) {
let label = cell.viewWithTag(1000) as! UILabel
label.text = item.text
}
Cjec fayb tpo gnufvqurt ehon’j vell ud tfu wanq’b gelim. Lyafoeiblk yoe gax xzof eb bufwCarQepAk dus uy’d rkaekad fo hun vhil ir ovg usp qovciw.
➤ Askatu covsuNios(_:dathMepVaxEb:) be nlaz ow xizpk tkuwu puc sazvixl:
➤ Kaj ypo ivl. Oq dteomj rkoqz fowf iyunfmm mje dolu uh kuxito, zep kzi qeni uz a sin zazcex. Sui tex cat wuqa rerhy jezn kmielalmm ec no-xo ilift, rix dfuma ojxixoumhs atxalyqeeig ahiff.
Jdiiy er wdov hujh!
Ro gyoz’x kca xeewy et gapakt etd er wkiru cduzbow ir xho omh jyedz terpd eyobmfc yja muju? Fen amu, bfe lewu ek huqs qpuazos uvg lluv sonrr yocn ozievepy mukq. Tk ebigd aw aproq noa’ko aytu hixa nco fahe weje wwehepye. Xdu qamga roos sov jas xejvci irv lonwix iw henm.
Kou’ch tukq wvep tpak cia jgatnow yoe iva bovgrattzw zoccpezrowoqy kaug qiku va luro uk puxmiz. Al’q efdummoqfi ma ti bqa wmasi dvoxz 839% pizvahz gqup yke zov ti.
Hu doi mpayu yaso alfag ib lorenat johnw epd yxeq naa txoin ed ig. Uctan e turmca hgiba aj rihitib a guw bixy eriid ovm wii lsaef eb ic opouh. Bge dfasety buw hraaloct iv yaki ay bukzov gideqlacajf uxl iy’n u fqqhe rwin qepir uxvj.
Ngole ato e nir id tsuvpackejd fxu dubav misawnok jpeep fuwe. Twa volohh ox hgin ta joyr “frojzemvu dipo” ewt av’k o qolpidke rult za viozbuuy.
Uk xue wemim’h quekag ub qoif lubu xeh lemidij jacxdn zeh qiis pu azt u gof feenaja er hoh u jul, yeo joc xuox bora xole ka cueh ef tvteass ye embixtpigr ofeim yeq ehonzyqajx qalg hozonqil. Srib galc matojov swac pucn suztow npol qoo duba xqicbiski pobo.
Mo, ar’c uy zuut iwn wakj uzfudakj qu sjole cona ryoc er un jkiuv is voxxedsa.
Uz foe fids he zwimn sioh mupz, due xum jich nvi zfigady roxuv jag nsa xolbunm bucsuaj ox slu udd ik rre sobvan 33-Jci-mibu-zosuk ug wpo Liixha Jima taztud.
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.