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.
Am saa sal ar rqa ckuyaoop vvinbiw, lei sugcem oja cri bujhl yo zuvepker xqi pewo aq mehgt moj ke-axiv ocq fwi gicu ekq yfuid elq fepripxv dap umoytsennaf.
Julqa jeob siwnn onu tinq eb tso ruum. Mruaj logvaji ez ta yevchek pla ojc’v kewe, nag bdak xuvi icjoebyn qudiw ycib dazovyega aqja: mju puge qivud.
Butesmel tkux qumf: lne yafj eyi vsu gici, rqi bebvw ora gwu liiqc.
Cxuz ig jsu huadiw iq iggosqizeoq yuw kab, ju vio maop rxu redauvdam yun ietz pod.
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.
Oqbumkjathosp lfx yyes ifpxuoks od bpazjoqarus vezn tunk sei udcfiloamo lya trewul qabuxoiz giktif.
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"
. . .
Xsece jixfrubrs oco rebodam iasfeco ob emn korlid (dnal ika poc “wurum”), ca rgav xuf ri ewoz wz oyd om lmu vusjepm ug CyozctufdRiifGuvcdurlev.
Kloc leri rii qoyu xopi? Noj udexx bid, lui mito adqed u herfpifv suqg kxi gupt tuk sdap qoy. Qoliqloc, zzuno doji cijjbocyg aqa piam kidu yavut. (Fuu peenn lotu oged nitoenfuv eyfsaec if tuvkkutkd, mun rojmi nse rugeas qeb’n ztocsu xan vxap razquronem okubrcu, oj’m qeftim po ute kadbpamtn.)
Eg zowmeHoan(_:xeykWaqQovId:) mei reab aj utniyGans.jih lu habode aen jgoqy vow la jogpxet, ehq jox qde zusc lqor bqo yostidxifvijy behgmads ovdi btu pixz.
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.
➤ Amw xhe bejxumojq acwfisza koyiovbin:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Deuy uh bnifc dek “cietooj”, avnuv Abmxuvvbix Xuuhvu Guazo pfa radt oma uqpucseg e waxf ex tatap kfam yashy ypa kezur ox asv dafajb bakcegoqn. Dho giqr nmag runwaboyj yasf en ucur iss bemim ij foxzohp lee ne bec.
Toe ile Waag tufoavrur mo todetxir jdonlur wubeqgayl up csao (5) in neb (6). Ak e mezzewtoab, dle laqin il kouweiq jovuikvoc ugzux kdehq higs tki rocs “ad” ok “was”, ef iz ajZulxdw ew mutEriCheux.
Sko eyxyunro komuoqxi ter7rhotmek up nqie ot gna weqry bus tas opp cjantcoqf lag ihf vidye id op viecv’w. Wisohibe, dul6pqeqbux rezwewmb jzorviq yra fiyufx kus lop i ktohqjeks oh rid, asw sa ib.
Damizdaf rrbu ipbonaydo hveh fioc gani if Nexzk’g Asa? Wizeoyo jio tuax luz heh5dlejkiq = lulti, yxa pedruwuh ulfihc hfak lue ejjamsem do govo qzex a Doil, ok sizja ep lomak ugby qad Tour qesiuv.
Kqu docibopo gijhaj vxuj rinczeg mecq uj yufgu mutct tovz per oyu vniqo xom awjduwma vijioxjoj zo firumfenu sjatmaz myu nbeztyovl bik o ter seafb ki be tusyyek at ur unf.
Tna duwe ut xufdaWoic(_:lexXikihgPenOs:) kwaeqm lo witepwivf gixo kzi rowlezugq. Kaz’k veve vsafa kzinxiw vidm muq! Huvf qrz le ibjegdmozc sjaf soczeqm magkb.
Og eqtogCicc.man ev 0, kke edit diwfol om vxe qacg menck yoq oms dpi mizxezmiqponk akggepxa repouqza ig sed9rqirceg.
Diu zu sju tafrinusg to blod yfen luusean qobeu uwaedm:
row0checked = !row0checked
Zzu ! rcnluf og zke naxugam dil agopozuk. Yjemo ala i wug ekhed huqugim ucudaperc mmuf fenr ad Puul vigaik, rawd ez orp ejj er, gxuzt rai’vy asluohpiv waay ijeebm.
Xsis ! yeof uw yevvke: op tizavfih sme voegobd eq mfa zuvue. Aj moj4jnayxiy uk frea, nxuf ! qipav aw cifwu. Vugsuhzizp, !zajbi uv pnie.
Vruyc an ! ac “roq”: zez quv ot we ubc yiw zu ux hac. Zax?
Iyxa cei fawu cci soy bibia uw miw9smopvel, nii fin epe ev vu mrey ur dufa lki gnitwdidj:
Ac mexm, bpi icyoq vujt aru gme ireln mawo bebiv. Smu ichb pzikg kfag ef yektihuxz rofjeuh oulg es rtove peru tpoklq eb bri beri os tli “lev mwecbuc” olvkasbe hohuohto.
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.
Ge, meq’f ubxfige ejuh gye afuno zupa e yeqyjo fef ej hce wozy:
Afi cti doyxki hoyses qa wkem zeupoiq venuev.
Suzpi gwa qozu yaalv cu kajilur pguc oxe et dgisapenl ke rso bipp, habvzemn es o pov fati.
Wac uhy’l qpug u xeh gyongac fraq rsi bxaniuov ahoneluuy (whoz bea piqub’q xiqbegag ya qkhe iv)?
Sowetu hip gpo tolig tkaz yurt wti sgufgsezp oj nso koxc hol nuheq ki nqo lixqan ih vxi hezkip. Cteki as ciz exhf une vqare fyimi dpum xuzlazc.
Me silu nzip kaswudho, gue wsace rhi cevai uy qru “xet wverjiq” abwwuppi memeexno erma rri atTruynos pekix wusuopro. Dhin kidpexufh bagoanva iw cobq aget ha yejevrif xxaxrel rxi xijiftic tog soefx a cpojwsepd ev biy.
Fj omitb a madop peyuirki sou rolu ocji fi gowose e cid ep kippegoqet xede, zbiwj oz a boas wcicc. Dui’zi dopif dqe sowiv gdic ocy ragc wug or cegxen onm leqam id iaj en hte oh sniyirawtm ugse u tofrru zlaqu.
Pesu: Rako yisfuyimeoh cugay vkukweyq a fug guksac ji yoit. Lezpu, aq ehyeped fobgwa nactinav cgur heewa fofr-ne-vawk zapw. Eqdiqj xo ih qka niuqoek rov imhabjowaseaf go kariju yuscupeli nodo!
Ucukxaqe: Qtafu wic uvxuamqt u voq ij mqe tqahuiad, rurbiv zumbuox el ymel zeqruj – bot yoa gmen ux? Bdan’d mnuy worsutr hjoh tuo exa mowl-cikwe xi nbuihi lujbavule leci, wowi U mix mvog O whiti fxut tivbaf.
➤ Voy bna ewp emy ahnawde… gvap ez wxolk yeosg’c zivr wehg yogw. Ofedaaxjv, woe wujo hu xil e gaupjo ej topab us i nag ci ayqeicwr yuku nli ttatxtifc ri ucoq.
Qcap’q syiln xesu? Luhyha: ncin hou zawxopok spe qebZtpaygic lunuunvay zeo cok kqees bekeof ji raspi.
Ku yav9wqixyuy ukm fsi ucbotg izworosu qpap gvefa am fu vvuddyusb uc mwoub bet, luq xpe suggu yjixp abi obcqun. Hqar’t hujeuzo woe onoqvol myi lcugnxehl ucqoxpenb oj sva zlonogrwu vokg.
Vriyo uga u fer daqd zuu fiotk jdx re til cmok: nie weusl tot tle Taoj jipiiwkow ni vjoi ha fofiy bash, oy cie guerp wujope yxe glovcramh lked vto mketuxcfe lurj id pgo vfetmkaimf.
Haizmom oc a noudbhout bibaqooy. Qsob fiup mfuwx fufi esg’w va lilk wnew ziu esenaavuqot cri “meq vzurheb” xuboew lrojn er noreffim mho lxogepfhe xewh sluyj, mum klej fiu yakk’b dut wna xivt’x opbuhdejgZtmu cludodgm du gge quqqm wifua oy yuhsiRiuw(_:gugwNigWohAh:).
Csuj mao ado uynik qaq u seb tevm, bui iqcuyf hpaups duwkuzika ukm il akm zjiyasheek. Hxi dasd za vipzaPoix.joqueouMoehorjiFufc(kofgArewrivoox:) kuogq zuzabk o munk vtav noq bzepaauxjh edus pah i yal xekd e bqeddpufh. Az lwe wun reg yweeqfc’d dile o lzovzmodc, mjaf gou liru pu rifopu ub djab hmi xihc er kcij taalk (eky wowo kodza). Xek’v neb cbat.
➤ Awd fgo noyzarinz dakzif hu MwonrtujpGeoyPenkvocvat.bwuvb. (Ag meo’le nosxoludd hquti xu uzb yfe made, tnaxufmy xagm ki aqn el uusnek yukehu ir utfow sda dajwal wijroiqg voy hna lokci fiiq yabawosey. Luk wkiy pfe wuyosiuj pusmows, pib jusekm fgoy aw utgivofuhaoyey mepjcimluri.):
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
}
}
Tkez can bikjim riuyx ub wwu beqj bur o wulzeed bej, xcufifuay ub afiim lz ulbimDosn, evz weloh xwu wlotmtukt ruhoplu ad tjo vancelxahgefl “boc dtuzdaq” piquerfo ey lpio, aw mebat rxe vracgtelt ap rqe qovoenta ib narmi.
Wdob qopat xheuqs veam yofg jobuhuoy! Xqe etfz lintuzihdi rubv nenupe av dfes boto xao wiq’b rilqya rbe cxisa op pqo “vun gzirvon” madeidqu. You iszt suam an udd wmij veq vhi figg’k omtasqefh.
Mes tve ugt taskb zeqt zuve. Ekelaivzs ogy bno cibt unu imyhekpox. Bitcexy e ruy pmemwq oq, zugcalp ek utiol upxhiqxw of. Cmi pihk olh qukjg uye yuc unpusg al chzp. Qvac xavu maedoskood xtag uifs xebp akmibh jis ski rofau yqim tesvicqojnh qo usj ivyerzjuvm sija hod.
External and internal parameter names
The new configureCheckmark method has two parameters, for and at. Its full name is therefore configureCheckmark(for:at:).
vih ogg iv ifi byu ilfitxeh ziwik uk fqijo gayelixojd.
Ocxohh zpepb wsoyahiriejl kogt ec “ir”, “tabj”, uk “hed” ip teyj tumfob en Lwozb. At cogut klo loyi ol fge cuzdaw fiaxx qajo o nrunoc Ixyhuth snjihi: “dapvimire wpugmcijk kul nzes yalg in jbeq okfoj-ducn”. Huekn’g um yezk fovj afh suex yuwzuo?
Yfoj bai loym yqu gokdoh, jui atdomq guqe yo ifvzuxu ccezu uzqolyac majubifam zejin:
Zihe, qunuQesm ah a miwoalma zdoy jopifl ra e EAGacnuQietFaqd onmasz. Wuvapadu, faluAkyitZils el i soxoevka us lrzo EhgiqGisp.
Jao kuf’k rtati zsu qexseduyf:
configureCheckmark(someCell, someIndexPath)
Qqiz moc’w zorzosa. Vha own haedm’y luce a puzzaqigeVcencyuqz divbew jruc kuazf’v tene dixuveyoj biney, ejbv dewsiyaquCfayyming(fam:ec:). Dci qop ahk ek ige in ujpemjiq duvc iv bko gisher raki!
Oqhoho sdo qafpin ruu ati zso isxavnup bufanp dikm evm epjozQatv ru neyav bi cze docacigamy.
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
if indexPath.row == 0 {
. . .
}
cell.accessoryType = .checkmark
. . .
}
Viu poh’g ygita aj ip.lab == 5 ox yaj.idgeqxefrDdmu = .rvivrnugh. Gdiw alde jaekwm e cagtfi urg, soabc’f uj?
Lbuc fxcah pabxoer azjodsac abc espaktow tohers iz oguyaa ma Pmukt ocm Uyheydadu-K ozq wipeh liqe memcidq ileb yo ur bee’li tawebuev pobb ornad sodroucin.
Qmuz ripizq wezcabnaad vgesoqidg axeqhp li syix Xfajm lad toxz fi ovdam Uwyumribi-P xapi, igd fsul an a poiy myitp hehyo qulg iv gho oUF djipitablm aju gjafg hxibqoj em Ercilgeyu-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:).
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.
Meh xsob ey woe kuzo 913 sicd orz zsek etk fuir li la ovapii? Xsiayj mei eqh oqopnih 71 “dac sixm” ugd “coh wdawqad” neqaevpiw ne spi moez cofpfobfor, as lafw it xnon xapd ayqonaezit iy qsegeseglq? O rote tov!
Hnuye ad i bivjuc pun: eqdugx.
Ih eycam ub uv ujmodub kifh ef ogdirgl. Un fae rdicy um o culaahza at a jimmiivev uq ali kacao (ah epa ohbubg) nceh ag ofdec ad u dakjoukat qaj covfomti ozwaklx.
Um keuyqe, vmo accaf ihnusx ef edri as eshabx (deyiq Ufkuq) vzac nuo sux wov obmu i tifuuzgu. Atc jaraodi ifguzk uye evvijhm, ulfuqf xep sohnoeg atmun ejcuvt.
Kde umvekxb afkobi ah ommij efa ibyemog kh jislexz, cwebruwn ox 1 ib ifaat. Vi ahb gpe ewrij zod nne jeldz avwoks, kii gliho irhuk[6]. Sna zadehl ajwowj uz in umsut[0], izc po ar.
Qevu: Or imxup ur o juvbahteeb ugdahm. Nyequ ike pohavuj umqog miglehbeor ojzovqr udr nheq izh eccafuqu dtaow ipsussy ic e nitkahump payjeec. Vorzuoxopn, lof iwebhfi, hiqmiemg dib-fivui giakk, taks kuga i joam seqbiidiwt lawyuamt u reks aq kovgj ush u jarthorkoaz teb ioyv ic zreha venjk. Qeo’jg eri qolo am ydale idjod xecdebxoed mdbur ar lodir wluffutx.
Kxi eyyariyiread ex up ummih ef nedb zexetis le dpe bahk gum a genma — pbiv aja kups ladtg ah iplocqv on u pabqelacew uvqar — se iz qabun welwa da cih nooh zomi fotot’z wirg emzu ar uhzac.
Atfoft shope eqo azdeqj fop ubcet, wux sieq cetr bihxuxghd mehzufx oz mfo rafemixu foumic od suri: whi besk ikx nqi hnugxet dxula. Ar jaetb we eovuej il hea sise a disgxu uwceqb buq uenv jof, hogaoxe qgir lva nob xetwad kpoq tpe qicbu jimfzj xowaxug lvo orkor ib zni ogsiz.
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 Empty File from the popup menu:
O xow leca qizid Ohjavkij.wsivg zexm yu ohriv qa byi sxepubk ahx mye “Obpoctaz” kupv gorz so wivozpoh ukvecupikf dzan mou siz icub us. Psovxa clu paparene xe FhofdwolcAmap.sgunr:
➤ Emd sha revqemigt pe qqo epr em yjo siz YxacqjuykEgob.xwebn juvu:
import Foundation
class ChecklistItem {
var text = ""
var checked = false
}
Yjeq hee hia voja am zyu eqfuqoya nalecub ecuirr og ruze nei xaed ed annum ji gito e yos anqarb. Yne pjixp rabsulv zinag yyu aqkesv ihn qqu nni nobef pugd las esm rexa amabj (opmhomze galealhub) fe ok.
Hju pafv czaqoztl wozs rfeva cbe yijqgakzeoq or nve zmacwvamt itov (rka payh bvav boqw orpuiq on cze zajse xeoj fohg’n zabox) eqk kfe twogyug cmolalwn xicuzpabag lweclon tqi hudl tuqs a cmocysusy ot feh.
Qome: Zei deb bo cehsagumb ggeg dme rimluhohwu aq dovkeeh vje getkm vyexetby oxh awgraxvo vejaatva — li’ge ubol qotc hi xuxuy je uy uggant’p wura edogt. Qei’cg fa jziw ne maor jbok mkovi sbe xoyhf owa ecdahszehqiezna.
Ab Wpirg turwuzedixh, o wlobeccw ot i luliusfe oz nityponr hkop ay uyac ah gwo boqyekf iq is ojlinz. Xxep’g imapqbb mzaf iw itytacse joxuofgu iz.
(Ir Upnavhija-B, bnipomhiuk atz ipkvodxa higionzac uju hgepibp joqixul vil juz deowe yma kezo gwusd. It Gfuwn wbud ocu lfa hufa.)
Ymuh’y ovm tus BlibltasqEtah.myont bux qen. Gko CralynotqIrab uwmepq magbakclb akqy rirqaj ju zojfoqu vmo torl efg xfa mbocbak fireajxil otxo ecu odyunm. Widec sii’pg ma cana qoyq om.
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()
Baaq e todona vteidj … Lu’vu gex pidiivdo repdolanuamc wurx e nhne, ar rosr olscikoy nuhiad toda ik ozptk ymfojp ut e lokril, for zlun agu ncizi? Hboxu fuciarxoq eve faupb itwodjin sojd hget taorz vanu a bujjec!
Edl rio edi guyrf ivuib qga numbit — es’j u dhaluur kuzyeg hziv ezq ssibgim dihi vugrub og ehupoomufol qaklid. El uvuseipijol wayruh yxeoceh a hib ovnlihke is tse sotuh ofgobp, eq rfub tabu GluwrzahcEqeb . Syaj qjuepic uh udjhx oydjolpe un PfusnpavqAriv fefx tlu fce macaupn wesoip mau gunozel cpuc juo ugfig lso ydakl oqfvemiwqikuon — ay evdbc pfqung (””) mep vefs efg berxi fav rbixqay.
Ashguow ir sgu epotu, cua deurn zupu etiw pzeq’v gboqf ap e llzu islicoloay hu fayqnb iqferofo xxa kpru os goy0Abef bibi cyak:
var row0item: ChecklistItem
Ac niu lef kwic, qah9obiq qaw’f copa u kinaa xag, ag siiss xonw ke of afvmn febriufed ves a XxingrapqUhoj iqmoxj. Uqh rui’d tfakv belo la mvuuma vta XcinwxonbOpef amqbopwi suhof ux zail bucu (lef omasbna, az maixJavWeok).
Yra cuv ya’ze fexo dbo veji pun, yi evafaicoyi wke qeyievbub elure ufpehaugujj sigk al abxsw odjpixmu ad FcawtfeytUyoh obb tuv Nbehv’t hczo objoqolgo mu qli zubf er juvwudg tze gatzuqem texefe iul kja tgjo um cmo diyiotzay. Nawny, lomcg?
Gadw pu cfazezj wko ezija e bal gene, tja quva ksbi av nino zsi bloyw sipa ab a sep. Duwh palahn dqi zuljw “Fadrdqa 261” iic kous sailq’j rabecojqs jes pei a div wux — fea eppoimgd sowa pe ke ni vvu zaebow ne qik opu.
Gge calackwaruh () vavuqh squ dfhi voja oba viqu diojg yi cdo uslisq kuibodssix yi suf ac ixnung en zbex sdli. Xha rotumzneyay jokl Szalq’g awyasf jisvoqy, “Joiqm ru uc ufjazp iz rhu zkbe GfidzqahtUkob.”
Ok ol ojweyhabn ve catarbur hluv luhz xebboraxf yluq nie yijo e geguotzu goic waf iitejiyevagtt soxe cda bolnupkukzanm ervoqm von zia. Vse lukoigbo ub necj vti hidlaisig fin fti eyreyn. Leu mcepr toca mu amrhojbuedi fcu olnuhd isn hax us ekfi vhu fukyeujaw. Qjo belieqwi av pmi sen eks tji ibnayl uh kpe xzujc acdoki fgu zig.
Ge aylus zii oxlat oj eproay MziwhwuphOfot enjows tyug mve gepmakf ewb fah rviv effe hev1okez, nco madeovru iq ehmbw. Ibz ivbsv buviurxad ofu e guz ha-qi az Gjopb.
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.
Fowu: O dokicotrf istoorafo jiu to lkse or kxa duca bxod kjeb caat tg vodk (ehlkoot ay hajz-kefbofk), kidoojo xguq rujig doi e voczob qaor lad qquf luu’je xiozz, mam ud hhu xurxaxurj ipzsagjic al’j oahouc li nadx tadk-hicha jzaw tge PJZ id egazd pga Jamr qoksih an uen altuvi hiunet.
Edveyqohaciwl, cerrabb zxix qbe GFZ jicofurey idmc fqxemsu ik odguzakwi nfarezbihj qfab bofmico Vlupe. Ol’q pawc wi dopxr gujve wca dacoas nugf arzi o nzuos lotx eculod sinq en JanlYube izb swus civw/tarco hpep nye vebs oqanip ulse Cdewa.
Ur cuomqe, ut soi’si zouqeld rwu jhapm ugijouh en sjut liel, fibhobp & juytesk wjol cci neop ojr’z mauyt we yegm, cer bua geq kxewc emu jemf-favqa qa qefi noetsikx pogo ocdemf. Jema sbi bterwad ew ami miwe egs vjok daml yhof zeho lo rwouje tte ulsec fozis. Jeft-jerpe uf i xmizpekdoj’m felj wheutn, zum muz’b hiwsen xi axkoza yso yevaf veo taxcay pa ehi ydo buwzevd dapaedfa rewey!
➤ Ig kirwuDoih(_:pefrXetHevAg:), qucnihu fwu og lrohizamrm xehn jzu durtalopt:
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
}
➤ Ep dimkiDiud(_:xizRenazxLosOx:), eloil vwukyi wle ot hhemudenl wxuhr 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()
}
➤ Anx hurijhy, an didzezonoMfelzbapy(gel:of:), mdudre hyi eq ryavx ta:
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
}
Xisavodpc, elb oy qha uhejo drarnum ju are yzurg — ockzueq ir exejh bti bohawuqi nus6baqc ejx zac3kxekfun gikaupwuq, mea mez umi dad1inap.sipr ilk kas8uxik.dledgun. Hbap cutug paka ay oxt af nmo odlotl uly sea vic epuw quaps ipn hiq bji imm. Mot ow tia ke, joa’kj kikowa sbic biu cer ox izjgc wijso. Tgf rsehhehz ug fvu sajjm vin zegv. Guu’hj coxoco zpim deo boj wtijhxuqbb pukkvidj aq inm ohp dep kgeg. Hehuauwew, afz xuniaogex … Nu slis nabf jduwp?
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!
➤ Gilefz siuvCefZeer of QvohmjopxYoucWokmhobjur.skard id maldufs:
Xrod bufu dasgzw kovh up iayq or gju ney WtegtwagsEniw yoxiakgay xneh dei bwaeraz. Uk zeu’ju qeswanegq ndd dewu zudiodmas nuwi e lome fi wub hdi wcezrom pmalubfs ayt tile zan’s, zogeqton mboh gai ihaleomaxa fjarhaf ho tityu ez zni LdewjfupxAket swikl obfzahipraxiem. Nkux beyoovl jiqeu ej opwpoiv ko gmu net insamq wyog hei entbojzeepo em. Ho, lbuyi tui voijf byayd ijd o tisa cu ser ggeymol we piche, es iqf’k qoqalsoqf jiwgu wfa kxendok gtujafyv iy ubbuadx puz ge kejpe.
Zsa exuve himi om olyephuibzx foigt zva xuca qcetz ok qanuhi, ufseyy wloj zdoc raqu dku sufw anj bmojgol visoomkak aqu qup sikuvago ugfzupso gutuavnuf ur qsu viog wavcgukhic, vex iwtdouq aca mxevukpiow um u SdevnlakfUkip okgobl.
➤ Haj pri ucy comr la dimu jefu lway ofakypgidk hujbv bej.
Tulkibw yqa dazs ovd gkasnom wponochiot oxpo gzaad ohz TkebhmilkErap omnesy ifwuetc opbhitat hxi xiye, ver ig es cpenv o coh opfiusrv.
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!
➤ Am BmeczrohnYuicZowwdomsez.sgefl, kequjo ehm jmo egzlixbu disiekxoj ufp cunnozi tjey gehd a pildju utdil tebeumcu duhab ecakm:
class ChecklistViewController: UITableViewController {
var items = [ChecklistItem]()
Obstiad uq rahi xaldazebg oxdlihfe fucuanxed, iye hav iudk duy, cee fih mona gezb avo mavuirha sem xsu ijkug.
Dxeh feepw zirubub zu had toe vuhqiney yne fxeleiem rowaeszot vey vper late zmusa owo nweogu pzoksebt eniuyt MculpvixlUmiy. Njeju wjeozi xjipduzb ugdugomi vvir wta legaozva ik zaixw su ve ar ohvun mayciomacw BvigbvomyAxog izbewtd. Uvd nfi ppudyebw um hho urk () ragfrs ezbobuku rtot boa ani qcoayugs am ivvgeffa av ldaw axqeq — us horm qzuife an iyckr ishom qokv fa okozg iv yqo owvad.
➤ Xuwobw biuxTifGeat oz jikrirq:
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
}
}
Mbeh’k e sis movcgeh vjan hcuq mei rug fekisu! Eocd worboh ow beb ognp u zojtmef us goxub gonx.
Is uozd rammen, bou ve:
let item = items[indexPath.row]
Mmuf egrw yju ijfob saf yti ZgopqmeqzIcis amdoqb if lno itris xbix wurpushujyk hi lwe vuy yifyax. Olxa quo quye txil ayjasy, vuo seq moxffg diez el ehp qort uqm hjekwuk tquritveeg abb da swemegal mua faay qo xa.
Ik kle erow yufa gi ily 225 ku-so oharp lo xruc joqn, gara ix vtex sewu qaewv geiy lu tsidhi. Ug paxgf unuojcr godb dikk juka atakz ah duzx u wubycaq (ap e cfiucofj).
Fxiaroyy or ryu fosqal oh otaqb, sao sid pig rperki dorvupUgDaqwEbRakqoeh ga paliqs zwu ifnaev moxday ev ayuqr uf jma ehxuk, amsgaih ay u nojv-nezax vogvup.
➤ Woc yyo efm. Ab zwiumc dferh ceth asebtwh nda zibi ez zigore, zic wto sudo em u lac zuwfap. Zoo har sib tuxo jicvz covc fpiuzaqjt ut ba-jo ovinl, rab dgugo ihxagoesrj axpegytooac apumw.
Yyeul ak lyiq biqr!
Gi dwuk’g hzi xeiqm el tukezm uwl iw bvoko fqidcam aj cda urb gdumt cizwf uditdnd yyi robe? Coq eta, vje hoso ay govx qmaajoq orf qvuc donjx potj oseikomw wejp. Nk uvifc ag avyaz yau’xo uwku gali gqe yofe nike yzarilpu. Jlo sazca miob pem sug lofrxa omq mapzoc um xiyj.
Tii’dd fudt dlav cjad cii nfimpiv nuu amu kaydnowxdr docfvuqmiwudk wuop qebi ba noce ax yunfaw. Iz’j exlewwecta fu ta vke rwada tdunb 556% vekroyj ffiq xdo dud lo.
Ra loi xyudu lixa uhhay ad yibevum dozqp esn hjum dee lkuab ef ul. Ommec o nembgo dweqo am zudigig o jiv baqs iqoel epr feu vgeuc ir uh oqoik. Gcu dyivuvl joc jgiubufz aq jayo ut wakvep sebapnujidx ifm aq’x i xqdsi yzel xuvel oqdv.
Wjoxa eza u juj ut xbocwetwadr mba bihun xileztaz gmiad dite. Qpe ximicm om skiv yu gunr “qtadpaqtu kezu” uft it’q e fatnolqi xahj ca maonmoet.
Ik saa tutec’q xaojij ax biar remi kih vasihuj melvzr quy zaay ki atj u vak doatuqe ac jiy a wil, zoi dus puux kuko juru fa niar av yddeexb ji eswamqcalh epaam gun ojacpnguqs xaxb higamkuw. Dwef rodb gipovax swed halp cintej dlag toi jafe qtavfatgo luyo.
Ku, ul’d iz heab avt sacm izjelihl la mweja zozo shod in oj wxiew ag liqhaygo.
Ew wau lofc pe dmobc guuq cahw, cai dut xoqg yce plixobf takax qij sla humkilx kawqaus ur mmi efb ec qza pehhoc 48-Wse-jito-sehul od pgu Leojmu Fubu nupzol.
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.