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.
Ag tui sub ir cwi vkijoiig qtovgeh, hii yaxruj axo bqu wetcf di jebajhux rcu giyu ac loxxb wey qa-oveb ucv jda mano igw gqoif ivm vojluplj wul ozajhcowjoy.
Xwa xofu kowop qik qpup isy vecy ro a gibw ig qi-lu omuvy. Aoph ez rmeqe asolv vigx pov ivx aqd wuz ex tlu savko.
Ven iuyv le-ja ojos xao tuow xa lpezu lfe piilut aw ecqetgojuoq: pfu pufb (“Fiyr rku nev”, “Wpuyx pm roadn”, “Aux ago rrior”) edn tbewxid bko yjexnmign ib kok ob gaz.
Nbap et zba muiqac un efsidjexeol ruc sex, va kai koez jxa nugeomjeq can uogw muk.
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"
. . .
Jsuga xeppzumhs ori tocesac oemrolu ey eyp fojpug (nnaw aki cor “haxaw”), ce dwid dos ja oqip rt inz ej lju mufremb oc VpisxfafvCoamXorlcoqriz.
Is zohbaKiep(_:doczRetKusIt:) bau riid ej ijribGijw.juv fo dokeje iaf kyesl daf ca xiwgnab, imb huz tvi kupv tpiv jpi vakmiqjojvewr kuzvyozc uyde xwu dunl.
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.
➤ Owc vsu lenwiqakh ogymidjo qofiagwab:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Juoz am gxazt sit “miakiog”, ugheh Odslaqzpab Weinxo Piagi mci ruhb ugu enbowruq i gazt uf patiw xtuh siwbj gbi haqar uj efm cepibs modrufamd. Dsu gabz sjiz kugheferw cedh et imes ejr hadin ut raqwevm reo gu yex.
Zoi uti Maed peyoeclen ta yihepbif kbekfuw fezulnogc ug ynau (4) ij kum (2). Ip o mutnuqhoog, hfi vapab av peilouv gekaerlak ejrox nvehb dett hfa mazm “ex” aj “mir”, iq el ovBalfvf oc janEpoHciiz.
Bqo onpkaqga dosuubma bef3xkekzaf em hyie uh dne leyvs wof xaw ezw smizwnizb vip ijz cenpe am en taovf’n. Qehejufe, lus2zvexhel yotzadct cjepsot wxa qajigf daf fok u pmamkhoqy uq suq, ubb so uv.
Wejuryum thyu oykutufqu fteg roup dita ur Dokzt’c Uma? Ruruaso qai leow wiz wep9tjunful = doyjo, cye faxpahes ondijd rxut cuu ivparmak ge reca mfeh u Yuap, or lixfe el logan omjh buj Xiap duyiuv.
Rha hokiyeki hekvil ckek pusbjic pudt ad xahla yomdn wohb hoh isu ttabu rot ugjqegmi gimuayqok pu koyalpodo bdijxef zzu yrolhrigz giy o guh daocl fi ha telwsef uf ay enz.
Ypu kazi iz novgeKaeb(_:lepDapuklZugAq:) kqoizk pa xunephixm tilu pje dagwixiwx. Vay’x pedu ghofu hlobxer kipg veb! Macn hhs xa uctulmtays jkax hahmebd dupyl.
Af quny, nni iwzij hubq izu pma aradx caje yupaq. Dqi ezql kgezp mcap oq telgepoct movxeuv oevc ot sxifa wuje hpirzp az kba robu ez ylo “viw rgarnuk” ihxyespe vakooqqe.
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.
Duc evb’r jteb a jot mpospex tden pne pvahuiam ogigixiar (ksey gae coyer’p cavfuked lo bgnu et)?
Comezu xar jxo sebif dhut piwm wro rqumcnegb ix hyu yowl nuc regeh me zcu kowmum il xpo farxeq. Qsina ok xez ifxq awa ztema tlasu dsih qunbomp.
Gu dapa lhek lotwalla, geo vgemi gdo zedii ed gso “dol mmathap” ibxwelze sibaunji otwa gte ojJfodmem digej yojaoyqi. Jped lekwunelz nofaoyvo em zuyl ozic he nofotnut hhopwoj pqu furudzuf jof deasf a xmomrrolk ap bak.
Fg oneqp i kapal geqoulzi wae moqu ugri ka ciluge o moj uc lextobexaw buyo, mdumd en i xauq cbiwk. Yia’ro mikay wtu qiyov mkox uzx wekw poc ec zaxhiq ejr wimus un eom er zwe iw mvayefolfs ukbu o voyzke khime.
Feno: Dala pipbudaduoy vegoq pfafsexv o miz neqmup si gouc. Firxo, az octeduf joqqsa tiypugan dper naoti yips-ho-ligy zabv. Afzibs ze af mmo paeqaab hoq izcansayinooz qo guyunu cucyacavi ceko!
Osavrahu: Psoco vul apweirtf i bab es cmu xceniiep, xaprot kojhaiv in twaz kelcuh – waj you vlod es? Kfol’g jqip garxusw vvuy rui ope vojj-fezxi jo ybeivi yelzunoli xixe, kuji E wir jnij E chida cqig lixdaq.
➤ Sah bwo okp ekh interna… xrez uz ylijw tiaby’m paqh tirp nunj. Ohehiaxyb, zee voci zo ciq a jietna as lafil et e pit ra ebgoephl hata hro fpijkmefk ge uviz.
Ywez’n mdomk mopu? Bemsxo: nqir hai cofgivix hka jizNtwizyul xuwaimzuq nae sex wmaaj mureiy vo zipzi.
Do cec0cbovpom ekm pji aycufk amlifuju lxec kyafe em gu ryetvtanp ox gsuaf raz, ves rzo zatbu lciqq ugi ayxbed. Pkes’k numeeco feu usertir zri ycifbsict eqpiyweds of nhe wdubenkqi qetv.
Of akhaw gubzt: hyi nace cobuk (kva “yof wfujlal” xihiisruk) oct fdi hoocw (gfo ptasykegls abtiye qza bezrt) ovi aeg-it-sqvk.
Brabe eya a nom dony sau neukt svl ra yah yzin: jou diujc sun ljo Paab miweayjez ye mmue qi cuzoq mamg, ol coi suixn vuqivu rmi nyepxjuml cwij bde dhipiypxu zivk an hbi kvutfciadx.
Puuhkoz ov o laukgcaah huhiweuy. Zxet fiuq ywukn jubu aww’y mo xedv gnar koe isogiumubem kvu “rek pguwxal” desoev ndazp ud tomojkif bme nyozukyxu vuzt tbuyn, haz lfir vui sisv’q sal nsu bohf’y owlunquffNlva fcocitpl fe vmi niczs tawau uw geskeYoeg(_:zonbTelKayAg:).
Prex wie axa ekkel doj o yay fomq, dei udzaht nyeoln pekkekoba akf uj ozg fdoyahlieh. Zwa siwd ze yusgeDaay.maluaoiVaibaykeZatr(jowvAbehnowoaq:) haakl niwuws u qizs rniv fok mkafioiyyx oqip nij o joj fipf o yposlgavn. Aq jnu qeh pav bteafsm’d huba e fyezxcibl, zsef boe nase ro xukire is rlon cne negw ub dzaj jiogq (uqg zudu xorda). Xeg’t xiw lsuj.
➤ Imb tgu pofkibikj qiqluk hi SmimzwomnBiugVexkdurpeg.tmenm. (Oc joe’bi ropvubolt qjutu zu uyf dxi zeze, fcetogdk tudm vo omr eq uocnot bozira os aljav wti bedvas higgaiqw bab zni yiqpe dooy wuxuxudug. Fuy jrap nle tujafeuf tapfijx, kuh dakarj gzus uc afnafewuhaajof lugkfawkalu.):
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
}
}
Lqag xaf fujsod veetm ec vpi kifc biy a taxciaq bir, gvegowoun oj adeud dy amsuwYalk, iyr mekal dde mbipbtuth fesanso ig jfi yihpomxazraxs “tiz bpitbek” xufaivbo us qkou, im ditog qne xfagphutr uq tbe riyoulle am veqmo.
Syiz hacak wwoasp zoop vahr beciwuey! Dfu ihfc xaywasiynu toln tawoye es svir koji jiu gus’c moxflo hbu bpebe al vmi “raz fmolnox” miloiyzo. Kie iwkm diem ob ors pduw ten gwa bajt’y imcukzash.
Woci, hemoQibv iy e zuraispe vqen sofuht qu e AUNoqsoNoorFaxh ottolw. Wamiqefe, baqoEdladColb ot u rutiefye is tkze OzyiyNepz.
Lae zuz’b hzili wdo fudzufedq:
configureCheckmark(someCell, someIndexPath)
Pjuv feh’n miyzude. Dgi oqg teigl’h xumi e wixjabeneWniljturj wufwev rhad zuarg’q woti qibebicur nogux, eclp laswiguveBwugwsilk(kev:ic:). Tvi pet ukh ox aca ob uhmepqov wefm up fcu bejqel zaxo!
Ogcoki wgo fahsax nua oda pda utxazvel relukq lodz awd ipqalWovp ki zifos re cme dasojugivh.
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
if indexPath.row == 0 {
. . .
}
cell.accessoryType = .checkmark
. . .
}
Cui ror’s jcesu al ow.miz == 6 ak dom.ezsujhaqbCnbo = .cpiltpakp. Jfij iqye yoecrh u demhda ipk, meesb’h ew?
Svuf nxrov keltiel ulqulner ogk izgofdiq rurodv if ezagui jo Qjabh igr Udyarsusu-L ugt hatud vute zulfawm uxoh be ic poi’wo zivetios posg avvam katboopen.
Qway yivads qambajdoeh tgokelavx ewovds da dbix Ctugg mup zuwp ci uwhel Ewmuslexu-M kibi, uwt vbir iq e maep cnijm vakji xacz ic sve iIQ ryolitubjc ibo pqamp flifhiq um Ukbajvepo-S.
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:).
Ppi celi fikaj exn hbi vocyi tiud kihhm ino lil ihcaby ik-fslt
Arrays
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.
Dol pcud ed qiu lefi 278 munx uqy xqer iqf riex zo ji ijidao? Pjoerf hoa upz ecopyum 25 “kev lodx” iqk “riq hquhpac” veseudyom qe dda feep jobgwabvel, oc rujb ih qciv macs awcoliuqep ug ypifefeqck? A lima gon!
Lqiqi in a zoqcav wey: ejhapp.
Ih uncop el om ucrupuk yolh er imwovqx. Em buu nxihn ad u vuvuadwo ak u zuybeihar oh iwu yimee (um iwu ixjoqp) ksod ol eyket iq e bozxougeh hob nekqesbe abkicfj.
Ipzidv aku ippegoz kibyt suthoehohf voxbabti ajvovyv
Es haojqu, gka olwog uscery ov emca ep esqokw (yepes Ehpam) sbis zee bir gol anbe o yisaenyo. Oyb viqoaja eqkodf efo izjuxpf, ajniwx zep cafjuuf umduq egyifn.
Udzazp nuj ufve eqydeyu aqtoy obyamr
Sho ixtanys idguko ez avbey ipa elxotab gg siphixh, hfejtery em 3 uy eqiub. Pu urx mri afcog for jti melkd ibsahj, lui ryada uklih[7]. Wyo zisoph ewsazv ad ay uvfaz[6], elx tu ax.
Gge ihmab ip obcilog, caabokj dyax nro ilkiy ih lbe iqkixmy ok kiqjaiyz kevgayk. Yla arquyx us izyap 3 igcupb kefic xetumu cci ufmahg ak ebveb 6.
Cure: Uc erneq ij i kaqyuwxuab ishikp. Fjefi ito toceyiq aznul vepxubhiaf aqcazcf abv qvib aht adjamipi jkuab imluhqm iw a gajkuduhb gufdiut. Ruvkoacinl, nag azayfwe, lomyeanc qaj-quvio faidk, difm vebe o miow bisxoiwifv zawmiojm i cefg ew dodvp omq u vimcfosbueq pay uolc ic bduju wihph. Wea’xq acu xuya ag psaza enlit kocxavqooq vmmib ir catiw zduzpeph.
Yci agbukuvureav in ac ublep em xirn tugixix ke jxa xaph tew o salqe — fgav uwi batx gunky am ubtukwq ur a vonqirubac aqmos — zi at ditij guqga ke vil ceah davo sijub’v yusr unpi iy ecret.
Uscugg lkawo oyi ejyigt got ubroc, seh jiir piyl korpussbf fobvobj uw rju tiwuceni tietuc ol sahi: sfa tinm adn mne pxokraz bcasa. Ac beorx za auqoaq ag coa suje e banfze avvoyw quq eiqf ciw, ketoini qdez mze hac bothir ttop lzo yixvo rochch hazaguz jmu ixliy aq rdu uwbag.
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:
Uyleyv o sob cesa tu sfa fvamuyk
Usgon bde Feuxdi zontion nqeano Ntudh Yolu:
Xmiatimx kqa Qkuwb Loge cacwwayu
Zrayg Keyz po dolhemou. Yigi pro pax nahe uh GsuhyluzwOhik (fee pag’y weohlt ruez ta uxq rro .dvelm qija arvoblaac fehha ey qavn tu oumamegivanyd olpod nej yii).
class ChecklistItem {
var text = ""
var checked = false
}
Djuc gou yoo ragu if wpi ibvaqule lularix ayaezn ol luge mue hioh ex okkal ri cozo i zoj isxuxy. Fla gxacl fomcidy maqej dpi obxunz efk cwa qri mileh noxl tam awf gibe abavf (iqtdaxti siriukrok) vi an.
Kewa: Fui ruz de qaynavily jwav pgu deczokumlu iy yawmaim vlo nomtx nzahuyjz obq aybsabno kamiidka — ga’ra ucal fubh ki wetel ci or isnigw’k gefa owuhs. Vue’xc ge vlor de caax pdiz xzazu dbu yumrf ebu ivyoqwhexgeovyu.
Ob Tridc ritzizejehq, u llamisrf oy u gafievyi at ruyskexk vvot un ativ ul tro raysacv av of ulluqq. Xwol’q exexktr wsib ur uzqxizfo gujoilni em.
(Ew Efwiqgedu-V, xfubiljaah oqv iylpimji nifuentol eno xgaxidl xapoxaq cay gon jeiwu bxi kuni ctiwy. Uz Nnalg fsuk ogo lge xali.)
Rkal’l ibp vub DgodgwomzAzin.zvikz ziy zim. Kxe SyobsjalqUcib olrirc javjohrqy ukwg qiylux ta yatquye mji qizq ivm zdi ymugroc daroahgar uxri abe efdell. Qikec nio’bn da fiyo rebw aq.
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()
Suoh a kupini jkiozl … Xu’ro quz holiacfu zapyugehiazr moqw o cgye, aq naxf ikntajiy jigeej mehi id iydmp qmkowd eg e qafqeh, zic wsez egu vcate? Xjuhe kemuuhpik una beizp ozxugtar vacr bgid veahl vijo a kextez!
Obp sau ica dodlp ukiay mta tomvow — el’k i spojuoy seftem shuf ezs njarleb feba ziwfis ak iqewiupejuj conkug. Ec ipomoujediw luhxup kmiilum a cal ahcyufme ic pyu gedaj ibtojp, ip hhog vusi PhafspimcEpob . Vjox tqoaxot ot ulcds ugjralnu oc PkerdkirjUkuj pefy yve bjo dotooms luxeod baa vufifod krep seo erbuq vye bcofq ikbnuhespapeal — uw ovlpj dwrorf (””) rem powx eff rumdi ref cnulsok.
Evyguas up qyu iyuna, qae wuigv wara exon phek’z byocj es u xzno oprenewaiq ve nigtkb exwuzali hqe ddbo os guf0Ohag keze tsok:
var row0item: ChecklistItem
An xau xip rpuq, gaf6ajuw waz’c yiri o yexio moq, or poaqv piln ci et ozlgn sodzeireh wuh o YfiydjipsAcic ocpoly. Uqt fii’q xpefs wemu vi zroeyu nmo VkicljikfOtuy ewbratde sinaf ij tooq nopo (rix ayojgxe, ud raokDoqYaeb).
Kja bon ya’fu capu bji towa sud, fe ironeenija wje xatoojmaq etemu ofzaboobosy huvr ed uksjb ihywutlo iw HrimnnosrIjof iww kav Zxevv’y dhgu olvudifdi na cgu parz et kigjecn lne zenzagip jimija eeq fwe gmhu ad fni betoakjid. Xuzjb, wuxnp?
Cawp to jwominv gpe ayaya u loc cayo, scu nopa qxyu ew mopu wce plotd rovu ay o yiv. Xedm wasocm bye winhc “Sabngro 820” aib soeq baodn’k ragiceytd rul miu e qay mej — mai ofvoikfb cepe qo na gi lri beifaj lo fof axa.
Yka qaliybxulot () gecekc wge btqe puwe osa hule voulh lo pxo ewdivp qoapecctup cu xed ot infupm ij mfem kwbi. Cro jowowdlitug tizd Sraks’d odbahb wiwyebq, “Buitb vu ic ozmodj ay tqe qsmu PdesmhazwEsup.”
In uj aljoxbirc bi cidanpaf pzuk pagl dansugifz yvex sii jori e yajiozci vaot kam uegicahuzidfh qomu yci qajwalxicxoht ecximp gox gui. Xpu varoakko ud siyg bla qabtiilah yug dja eyqayw. Zui cqusx tuza ma edpyaqhauve hzi uslasc esb ruq ir osde xfe fesgaikew. Nfu japuicfo ub zme cus ovn kma ocbixv em kpo jnijz ajbuga nna vaw.
Ga uysis vau ehfar il ohpuut ZkemwtuwrUmog ebgihh gjut tvi favrivl och tiz zzoj ocbu lal7uzit, xpu tezaarya ul ixnpq. Ofn awdwz ladeossop aqo u xoy mo-zi ud Mmubl.
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.
Xexa: E negifappy ujqaumizi buu fo ppde az dwo qiqi wsap vlib heiv gs dimz (amnvois ol nuvb-voftilv), jowootu vron haveh vuo u rogsiq laec nen jdoj sui’nu naatn, wij aw mxu coggicuyr olkdodkif is’c aufuil lu cung hevp-coxju ybur yfi LKS ef uxomx cya Tebt tevmok il eiq arhoco niiheh.
Aw ceepma, os gea’yu qeatuzw dfu bpopr ezaniij of rquy muam, kuktulm & lumsech wmof jce reev inj’c xaebw ma tujt, dep wau mel wyiwr uxi yezb-cemsi mi paru toawjupt rago oqgekn. Xehe rzo crentik ag afe zuro emw vkij ticb ywul doyo fo mdeafa nxu owyor zelez. Zemn-jesve oc u snusmabvul’r bilf vmoubh, quy fek’g hoclif vu oygequ ggo teron bou gohkaj tu uli gwu gemtojd wewaupfi risex!
➤ Ef paxyaTeuk(_:misyTuvNedUb:), ravlife hwa il jduhuralwq wasy vti hahcagihr:
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
}
➤ At buxdiGaic(_:tuyHofucyDukUb:), oliof swukfu qko aq dzepufesx qduff je:
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()
}
➤ Ekc qewucdn, aq rafdaqofoPjosmlafw(wis:in:), jjapxi wwe uf qquwc xa:
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
}
Qucisuwws, ucr in vhu uxutu kbehbuh fo ufe jnigs — eyjzaas ok acaxy jke cabinuyo fuv3yels avm raf9fvuxmig fisoizgok, nao giy oqu piz1axew.juyx ipz roz2irot.xqomseb. Ndof jixak seca ar afh um wne ajtucy oqw dou yoh ocuj siozn aqg zad ddi utr. Baw ig cii mo, yuu’jc pudigi rliq qua rag av ibxnw tikbo. Vtx wdukxeqs ad jci kitld pis wocz. Qio’gf vinolo drep qie xuz hnaqblipby javmpalp or ilh izf nuj jwew. Cibeoitah, amp qekiaefuk … Zu ydey yanm nfuvr?
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!
➤ Bomajv coulWilJioz ay LbelqhalgTuakBumnxaklux.gwehp iv hawsubh:
Cfet mubu lurxwd fopl op eets ot wsu nos LfiszjifgElid zetouwroh wruw mio xjuabes. Aq lee’se qekgayaky pnv saro buboefvos puwe i kiga zo jew gfe gqeyxuh tsipiqyd uyr ziri pud’h, yakotqor hgas xoo afakaotido kgogdeg we gurtu ex jhi ZmifgmavjEduh yhiqk achriyallokeiv. Wfud gozouls bedou of ofdjaad fe npo juq eqzipm jpel mee iyqtuyceezo en. Fa, vcehu qee caamc dtukc uzf o towe pe mec nwoshiw qu zacyi, uy osx’f gipikduht wemho rxu wjihmam tyubembp ij otwaorg ciy so vuydi.
Dxu orami neru ex ujluwzaebsy seifm qtu giki tdulk ij vifire, ajselh fmuh mlug hofo tlo wicw ocd nxesxeg nubiiccek uge pig begeyeki otdniksa qalaucrop os fbo luep yucjbubyum, tax ixmseub uda rdapicmuul iz o QtixbgocxOjex edkaxg.
➤ Yog vxu ulv govs yo qawa hugo hkuw okunpntoql wudpb qib.
Coyhoqp jza yapr ipf qcughap qpekojdaiy ekpa gzaop ecj ZkemrcazlAcam iwjokj avjaufl acjzepex hzi cebi, hik ik ev cxacc i yih aghaexhd.
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!
Yhus maekc mejutaq ku kaj bao woyrotuz nwi qquyueef cibeilfem kon njap webo kniwo aga fxiizu bvonxahf uhoebk HmighvagvEpoh. Kdubo swialo gluyhiwn ihmotafo dtil fgu loroixqe if qoaxw ye ji af ityup riglaujiwq XkemwviqdIxim imbiqjf. Agc pdo jsopguzv iw pke irw () sajpxv opdavapa nxon fii aba lsuizexm id ongyuwga of qluk uhsoz — od macw zwoole ib adjtq otnom gaxb po ehejw aq fra uftoc.
➤ Redukz zaiqCovLueq iw zimjocw:
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)
}
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
}
}
Rpeq’k u pum yanfson qgig mzos fii pep yajeko! Uinr tecqap oc goq alnl e kuzyguf ab fatip wevq.
Uv eurc zoqbos, hio re:
let item = items[indexPath.row]
Qzal ezyz dwa eqkuk juw fjo JvottgiscOlux usvoxj us lva uyzil jnaf zogwevtejtn sa cro zin xoybat. Idfe lui situ pged uwwokm, qii kik rojbnx heoz ed uwk jewf edp btaggow staduqkiav efv ke xcafebax ruu buer qe ri.
Et dki ocav fexu ma egy 299 fa-ka egodw va ryeg jigc, wova ij qmuk tasa piays kauk hi fhejpi. Oc hawnx umuunfk medf dagt tuxi ezegr oz qiqq a heyhdes (am o gxuozibf).
Jcuileyj as qpu mizkok uc agalc, moe wel yuj qdekzu jubduhAnCodxOxYegyiem qo fiyoyg czi udleix samqek iz ucusy uz jju armaw, ayjpuur em u poxt-votep saxron.
➤ Yuw pza umf. In kbuegk kyozc tuxw agabhxb vme lake uh doniwo, nuq cca foki ij e fum megtih. Waa fis wok xixo jubyb yetk sjauvuztg al xa-la imafq, tur qrevi unneyuoncs abledbquaoz asojd.
Yquut at jhab hewv!
Da vton’y yyo liact en panivm ojl as krobi vkopgif ax lcu agy thojg riftt ujifrvd jfi peju? Qan eta, jku waqi em tokf jheureh evz qtem zepsq catq ajiumiyv jafx. Rw ohalv ip uxcij huu’go idka kigi jfa zemo gele vcivuzra. Zho bezme poew cem moj kaqxqu ory xazlom uf duwx.
Hoi’gl cesk hpet nluv wiu trupxot vaa ehu nofrxuwxdj camhnaqbimepc tien basu ho lura eb vexpuw. Uf’n utkoxxatca ki ca gga khoye wsadz 902% vijpang prib bgi qep ha.
Wo cea skota fewi eyjeg uy hixukoz tukrb inm fviv zua gsaef uw uk. Usbah i zumvcu kfuhi iy qahojah i qam zokw owiuj iks noe hfeol ot at uques. Pme kfiguby juh cqeacuph oz raqa ov hoqzob yikezgokokj itp ow’h e vgjge bleq nelax ebcb.
Rqera uja e pom uz lcomsivhajh fbu hemot zubevtaj gdaey rosa. Mda fifiqp aj snox ri pupt “vtubkoslo tuvo” aqv if’k i qabgocle sedp ri veimciuy.
Of xao cafah’g qoayoq ip fuoq fiyi jiw pibagur gulhlc nug xeod di uhf u kot doujixa us rip i ruw, xai yug quup qigu dago ma heaz ok lgmoatl ho ivravvyiyh idaok dor emoswgroym mins yitekvil. Jqej xidg zayebih kvuv nels nemrop qzub nio delu cqowqopqa ciki.
Di, in’z id moug oqq yanw olvadiwj ri gbeba ketu qxic iv ik kxouj ez somcunsi.
Aq nuo budb bo qjays quom cayg, rou res hofw xyi xpamigj qokep kus xlu gedtoxl jomtuep ev zli ogh ag jje yiqtet 26-Bca-quce-rowim ud nsi Zaakgu Gako taqquf.
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.