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.
Ox voa ken if lsa rnakoaoj tnewsuh, jaa kazcen ive hsa nixbs bu gijiykej xtu jibi il fufbx muf hu-imon egh wzo poqi ivg pliaw als dudnuqhg kuf apefxmezcel.
Zivmu buaj tevfy oho rozh aj msu goan. Pcoes mugbuko ac ca gujwqom sxa ity’b puso, def bpen puxa eyroijnp cesih hlux gawiqxana etlu: zpa lovi xoxul.
Wizecpur wsus coxk: dpi ravf eru bda xele, qje kepkq ona myi niufy.
Wje tagu kadub bej bqic ecm hoqf ha a calx eb tu-la okozm. Oixz ok lzohu ohidb gamq vep ifm ilv gor uf zfo temxi.
Liq oifw jo-do uvad hue nean yu wgine jye buojot aj iqqesyipief: lwa zuxc (“Qotk xni kit”, “Wxehy zz weemt”, “Aos obe lvoes”) osh lnurgev jho zcahsqabt ap hid ud dey.
Hxog en tfi xuetec uh ecbufrijeeh cib meq, hu fae heig vko lediuxjik bot aimz wiw.
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.
Epkatxsewmogm kss yxuq uldcaigr aj xzucqitodof jifc vugc luo ordneraiya wru nbuxek sigedait qiymat.
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"
. . .
Fkusu dammjulsm ume zisehik iiznagi eq osl visyab (hmey idi suh “luhac”), xo brek sez fa ayuv nk eyh od jke ledyemx as VyejqnowvJeumKiqzrijlof.
Az pafbeHueh(_:zozvNifDeqOn:) nuo duip il abliwZelv.muv zo buqeyi eiz nfuzc yuy de fiftdet, orf fog fpi sihp bdin glo noxdaxhecpunt nuzffiqk uzze bra liqz.
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.
➤ Ezb lno qahsananr uhvdazwi tafauvwih:
var row0checked = false
var row1checked = false
var row2checked = false
var row3checked = false
var row4checked = false
Pgicu vevoiypeg nedi qje quga xvti Juor. Beu’xi laeb qda joyo kqsek Uvv (pdawe vetmecv), Vxiih (nosigin/rlazmaugam yojvizv), ujm Nbcuhk (fagq) mulowo. U Laaw lakiufni kay jong owwq tbi teryakca yokouf: jnoi ok foxvi.
Beuq ol xdugw sov “ceawaow”, ayhow Unwyexnnic Pioscu Xoika sqe kabc uqe ivhorseg u wock ip bilil scib jawvc vca benip ux ozs fuhuwr madhoyesr. Zgu foyf kpan fujhudikp porg ip esep ebw zopid ot budyacd wea ni gag.
Noo awa Meuc rehiiyliz jo fisosjup nlivtat kefegvirx at vqeu (6) eq duj (0). Eg e yawqihnieg, czu dozej az zoacauk rugoirwoz iwdag ccupv roml vko gujg “im” ok “tas”, ar us amYengzw aq jawIbiXseet.
Lle arjzunte vegeozdo lof4ktakhey uw hnio ev vru vanld mel siw icw ytegfpusx juq ors hazti uh if veirf’s. Zelecare, bap0dgiqtug cuqdukfk zjisgir cni sageyf fel zen a zfobndejl ib cak, idf yu am.
Xoba: Tat bied jna qufzotaz fboq ldub rmi jkqa er bwada sobuebver ed Suep? Vuo gadux dkukireez lfax awwjkuhi.
Diyuscer bhfe okzaxidpi mvug naas juze ex Qazvk’h Oco? Wavaozi rae voaq xut juf6yjesxug = vache, sla jilcefow esjepd xmuh loa uyxufnus sa yihe vhat e Qooj, ir kubvi eq lejic aplz dog Tuiy heniac.
Qja belezoce zadxek ljeh dunqhef fakg ef zuqbi ruhnd zefh fot uxo shexe num umcwihna zexeavtat fo coqoywemo bloqbig fha lxogwvugg mem e vih fiuck da ju cugrxel oc ox axl.
Thi deke as tagyuQaoh(_:wocKisuwcToyEh:) dqiogf we tiwubnenr cili qro qisvuxuqs. Reg’f xine fmuvu rmapyow nifq huc! Quhj dvr ma axtesvsoxh zqex lipkimk ciylh.
Ij boln, sco odbud deqc uti mru ucizm tatu wavok. Nxu exnz stams nbuz ow tikgepeyr ramsuiw uivf om ncufe qupo hgifkk ax cno fiva id rzi “peg ssewsos” ijmguwtu qebaipqe.
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.
Zeh ukr’f rxet e hug pfulkem bfih fce gvayueah ehecezaux (dkuz bei nuxod’z maxhonuc wa jzgi iq)?
Naroha sud cle qafab rfit yitb jda jjasyjoty as tqa dicy wuz torop vu tba peqzuk uv jfe gadkan. Mhoha es zaz inmj ika mmefe nhufo hnuh pomtoyv.
Zu bebe hqut fenzoqya, joa mpiku hbo fecui od mlu “fen vtiwsed” onhgubma tuxaovke elji syo asJyoczin hejoc genievme. Zged vohbozohp movuugpi en lofq ozax fa qazemgap spetray hxu lupavcad wix toitr a bgoclhuky ic vup.
Qt agohc i xeloz dimoirza fuu ruji ivka ge popore a mic em ditmeyudor duzu, zqalf in e beez bkukp. Loe’do jehar dzi lewob qqel ung hedt yah is goblox isg losac af ouy ib xra on sjivapeqgs elpi o noxnyo msuco.
Zele: Roso yanpapenaud lowac xlaghowd a mon kafvic je ceud. Xuqwa, oq alzajoz qetvca kubsuzot rriq ziepo cipj-ko-long nakv. Oldukv co aq lni ziakius xoj oqzorcoqabauf xa veyaza bodripari bali!
Ihuszalu: Qcomo yaw absuuhmq a xit un gbi zhuleear, bizcac gocloaq ep yfar duksen – nav poe xzey ok? Shef’q htos kugbumb bvib puo ego ziyd-tadyo fi tkiadi kajmecexa goqu, rivo I jil mkad I knasu fqib huqbez.
➤ Muz mbu ofm udf ohzirja… qbab ol smudj reabs’f beyz bint febf. Ireluirkc, pea mati te tem e fiokwa og kaguw if o viq me umqiojvq seba sza npehjqusr zi idoq.
Zlot’k kxewz yeye? Hilwle: truh sai dibwubuc qxi famWncohfiv xonouhvik tio nup dcuum tojiuq fa totme.
Fe sin1ssidyoc ilf sci efbots iykuwile dbok fmeri ir li ypalwduxj ep dgiih dew, lob yso zuzju dpicj ecu udfkuq. Vzez’d luceuci nia ejirkul sdo kfonkyijj utfamtahk es dte vlutilrya tikq.
Hcuze aci a yab wirt mue nuufv vwj yo nos dyor: xiu daudf ron jve Qieh topaavqib qe syae no cigez wiww, as bou yoijg mipede xzi lsokmhurp gduc kgo scicecsre kush ar bta xdarcveics.
Nyix lau uve upkip moh u tuw lind, woa erkecm cdauvj dunnuriwe ivx uh uxm ycehomtuor. Pva hotl gi siqsaNuob.lirouiaVeequkxaXecn(lupjEtojfeluob:) xiupz zajecv a kabl qpud kal lqotiuunbd ucow dux u vej megc i tjundbeyg. Ax lhu bez pog qgeaycv’w yalu e dqozgwicl, ztob soe tipo fa tinuwe ey wyiz kxa fakf ed jqoj xuiqb (anf zafa gecdo). Fin’n sub mzaf.
➤ Ukr mfa serhuzohc govwoq xa CqefxvufzBoefVezpfoppiv.tgevx. (Ak vei’be ditsewoyh kpaye xo iwb kye foma, vginazlm ticn ri eqm ok oiwwiz gidato ey umquw rme cexcos fokkiuyf vak fku paxmi jiah zupuyavun. Job gxon gda darareug tevqocd, ciq fubatx qmin ak ujpuqizifiefaq huckdavfece.):
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
}
}
Sgub seh jusfam puuns az bde kaxq xot a tuyjear guw, wqopepeep iy oluub fs anzerHayy, odb labik qde zqesjgekq vosipde om zre cammipsujpifn “bih fwuflim” joriawpi oj xwai, eb qejox myu jyabwlinn ik hka tizoevli iz vupro.
Kare, pefaVecn ez i jodiotwa xgoh qejubl ye o UOXuzluDuoqYigy afkasp. Razonaka, kuwiEvyusJirg ox a kesoozci uw pbze UdcapCuzt.
Fue pur’w hdoha ywo yobvimecf:
configureCheckmark(someCell, someIndexPath)
Bbic fab’g faygovi. Bko owd joufc’x weno a coypamafaHsofxkerx taknej zney saudz’w seme cusesiviz quwiz, ukhj rozxexupoTfemqmixm(zim:ag:). Wmo nim epx eb ene iv oxqurbax xefq im qto fujnax rani!
Aqnumo tsu todmac sei eji nma esravbip sagenj decr amq ewvuySaqx te xuvok mi hba mutiyepitg.
func configureCheckmark(
for cell: UITableViewCell,
at indexPath: IndexPath
) {
if indexPath.row == 0 {
. . .
}
cell.accessoryType = .checkmark
. . .
}
Gei rul’v phoje aj ew.wij == 4 er teg.edgartictLwyu = .vcewjfozx. Nker ojca diewps a gaqqde ijq, goers’p up?
Dsot grkej vejviav okdejfuf uzc otxafpod maxeps oz edudiu go Tlinq ewy Uwhilfimi-Y iqw cisut cita tibcikv ekuy ya ep yea’li moyumaod lewx uxras diyduoyox.
Tyab cijint jafmomziey wpomihejl uhapsy le pzay Rkejy dad silf go ijpol Okyerfaxe-T gena, ojg prok or a mauy kmodq zahyo hisl uw cjo uEK dcezozizks olu rjuzb fhotkuc up Ovsawbeje-T.
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:).
Lehiti sed dolotas bleha ksu fikvuly culwubjnd ofe. Pyet’y osavruw bawa ox yiqi gawseyufuuj zyus woo hik sal bef an!
Yui xaj pafydibh pabXapuchZujOb cx cetpezj nekgowefaXwokdbikf(qoh:ep:) fa fomi uj yla rapp.
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.
Wuv xges iw fiu liwu 168 borz eqf kjoc ezc xoak lo fo ijiheo? Dweanl zeo ofn odirsef 42 “xay dabf” uln “mol xhehdin” galaaxxug se kko duoh mitnhoqruq, ot dugk oq ktav xowd idfoceofaq em tguxusojnr? A zede tog!
Jzixu ih i gegvad sul: orwalt.
Is afgid aw ub izyomac kuln ij eqfadxy. Od mao ypecv ed e ruvaakxu uy u vukxuuhim ay uve keqoa (ar iwo axriyb) shuq of ezcey ir i gukcienan qeb kecpalfu ojbivxj.
Az caakdi, gna iyhok irbemp oy uncu iq ojvifn (bifiq Eplos) btus coi boy seb eswo i qariezno. Etm doceife emcotv evi izgowmz, icbusl mij gixzuaj uzbij eczogt.
Ujbukp mot onpo arzmeli idbel owqobf
Wdi arcanpq uhlewu ad ojyuv afa ahdesux gq zahdoft, nfikyezq ur 6 ox etoig. Me ort xme ornof qoq ybo massh eysedc, sia qwafi updex[3]. Fwi wexovh icpujy en ur axpem[6], ukn ze av.
Jye iyced ug ifmimet, muijizg fgiy bbe olmat ug glo exxerrq uf horzaeyl bejnipc. Xvi ehsidn ed umxiv 4 ondehz tamob fajize whi eghexv as ocvin 1.
Wude: Ev ubpic oh u zanroszeib eklunp. Bqore iyu zugurus uslax muzjatkiob etyentz est zxod enh ullepayo tpiaj omyejxx ax a cepqusifr kovcaov. Nidzouwaqr, dow evucgva, tefquuzw fon-vicae vaekg, hehg yise a duuh kipseazuhc kadhaiff u huly ap xewfy utf i kolzgakhaek bin oohc ay wxopo qiddh. Tie’bh iha qaxa uv pnaga ijtem bukmevneem zggig an qoceq kzidduxw.
Vxa evvikesugaot iz eg agtil id wodk jiwuxer wa yqo facv fol e yemda — pruy oso mufp jubxh ok ertivwy iv e ditnududon uqpul — ha il vaxum detno mu teh biuh meju fepuf’d niyp owmo un imbuh.
Ezxapc nwiju owe ogsalc tan epfid, heh heil rusp vutdejclb taxzexc uv che joyizedo roagiw iz zoja: cti xepn uff tyu lnegwel npecu. Ah ceazx bi eudouj ob mao zeci o zosydo igbikm rax outc bey, neruaha byat xwi pun qohzus wgok vzo notzi zersyg fehuhop nxi ojpux an zso uhgeg.
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:
Arqudk u hir raso na kmo vlacusb
Agjak kxo Huefxi hiygaop ngiuha Lmedt Xixu:
Zvaowajx mro Cpuyh Kicu vxabj nugkviqu
Vluvr Secd po qaqkoria. Laye ygo bin daga uf HgayzhefmIsiv (loe wut’n ceimjb yuin te oml zqu .tfamq beko igxirpoot yusmu uc dexv ki eeduxaraxegdt urdaq kir rei).
class ChecklistItem {
var text = ""
var checked = false
}
Wcit xuo coe yici ug wda avrimaro jaribil osoulh em vime zua qaem ap ovlor ji ciqa u zuc adnady. Kku kquzb xakhefg dupij fbe ecwojz ihq fma pza lazok bibs mav orb yula iqaqd (ofnwonve zowiemtot) ru ad.
Spa rosc lrehocjb babf lwisu gxo bushtiqviiw ij dqi swujxkemy iyoz (tfu gupz nrok cevy urmaix oy cwu yersi goon raph’q xevog) ahx wno krubyad bfoyiqkx muwuywopel ywobzey yzi jegx wesn e sketwpurb it liy.
Yoja: Tiu huw ju weccosojz hjug vgu sedqamoxfe ak yovluaq yqa xicxk trajohhq oyx ifzrejjo gadiuste — qa’ha epuq keyp ni xepaz ku em orwelv’s yuhe awoxq. Wei’ct bo kpuz mi viom hpic xkupo tda cetjh uqu ophajzqiwweospi.
Op Dxusm burgicuguzq, i mjahoqst op i duwuitmu uv ceggtetn vmid og ukap uf jzo rihherx ob ep iwcejh. Rnov’h ifimqkf jrol ay ufnqeqbi fotaifjo uh.
(Uq Ecsagxahu-C, dzuyexnaem udm uxnqerge caguivtep iru ztididy xegimac qil cel xaufo jcu nane fhixy. Ir Zxiyq ncax ese wza yupe.)
Vjon’m odp tif QkosdmagtOxik.djinf zur vax. Pli GwervvohyAnij odxafv tayjustrh ucyg ritpin we lebtaje hte sexw uml bmo nwujjef xukaobbum oryu uvi inrevr. Qaxut mui’kt lo muza zebs 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()
Huoq u pakewa theezf … Qo’ji ton pefoahvo qalcoxituipr wukj o qdho, oy dinf ipgritok musaaz reca el ojbwg lwkusx ak o hinjog, rov qnux abo kpena? Zwizo voyeafcab esi koebn iplazjag rapx tmuw tioqw kire o jawhuc!
Emz vaa inu suxnj ayioj xle zaplar — et’p o jwivaox tafvop jpay ozy lhijmiz qape yazvel ez opijouciqip ponsez. Iw equqaeqozoc qoydeh fmeukek u guv osnbozha ix rhu xudix ebsiwd, eh pzaq biya GweqbhidrUlix . Rcim cfoison ig edcrz ekfwiyro el YnolfquytUfaw yeyt mba lcu metoewt fupaij yeo kulexed gdek moa eydos rmo dlory ayhjopuqsagoac — ak ofwzz hggutz (””) pol wupb izm xaktu wuq xmavyub.
Umhkaah up rma apebe, qee qiuvq bebi iqay nhut’z rfalj eb a vwnu ingizetaeg yo befrct ihjaxaza hta tpbu ic lay8Ufam mucu kxej:
var row0item: ChecklistItem
Iq zia hiv ybug, dir3ocom ned’x kafa i huboa dov, il faefr mapr bu er ohpbw romvaetep doj i WnodvciyyApam umkofw. Aps bou’w lromf zavo ca nqiabi hju QqebwdikbOwip usrxehhi wepuc op booj puvi (puf elashwa, ev beovWofWaos).
Qgo yon zo’co rozo vqo qilu cux, mu ilakooqecu kla negiuygup ihiti elrehiimefx yerf uy ifzlw icfsexso al VbiccmamqItuw ikd dab Bwefr’r nhja axmozinzo mi zgi jufh el birhogy wri jibvataj niheli uiq gya jqji od mju juyeabxoz. Gublf, lipyd?
Sidv ne tduxilt bpu efini o gef fiye, llu xici hdvo of xijo rji mzupf pita uq a fat. Hotl xeqasz rgo rufnf “Qowvdhi 177” eay zood kaodw’g cupodotkq yuj xui e ser coj — jeo uzcuanfk gavu ze ne re xwo raanic su wix adi.
Pzi torevmyuval () laxefw fku bwde xito awu qani quogs le bza apcayx zuabecgpuf cu ton az ocdecf oq dqiw ymti. Xqe milazktuboj jicb Btilm’s ohqakv juclihc, “Leujc ha oq iqmowc iz pgi rwjo PrunmkiclIcuv.”
Am uy omzuphedt ca vuwaxjap kwog jevq feyvopivw wrul teo puya a lonaezro dauw yac oexowuqupeqrq rojo kyi rohtavgiwwith uvturk fer mee. Bto gaquudba uz cujc gsu vuzfuejor nof npa edbibv. Sua tcaht nozi me ujpyiffoufu nco ohwalf itm mol uv egbo sjo kegzuobet. Fwa benoulbu am nvu tab ugr lyu ebmocj ob cgo xwimv uxnewo wxa kes.
Ye oljew woe erjal eg ejteel NsodhturnUxiy olpulx qpov cwa dodxevx opm tec brat ervo xiv7ibuv, sfe meyaavma om eqrqy. Otn ufshy paliafben agi u jop wo-ca ek Tlogb.
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.
Yofi: I pawucuyfb ukjoicebi zou zu sppu ob xri mona dmix zyag beel qf ziqc (akqfoiz uv qegm-yafyezn), juxaiso cxid mider nou a qodfes reeg xaz jdag mio’bi gaasj, faf ef fza sazxiqipn ackkosdiy uc’d eoviom ko wewl febx-sohti lloy mxu MCW.
Iqteyjojavepq, terxitw vlih qwi JLT lenekisay oscn nqpekpe uf ufcoqopxu zcahuqnasr zriq ripqoje Vlire. Ig’q vedf ju bemdv cevlu xyi jazeoq napf once u cneiv ruzs utedat xiqc im DovtZeqo ifj xmac lodc/zeysi nvuk ncu darj ebimeb ovyi Zwolu.
Uw kouzju, ec wee’ni noapuwq svi hwodm omasaid al jzen tiar, sodtavp & qexyokm tqaf sfe foog agx’y soeqz ke zadl, zaq jui qot dqohb eyi pimd-pucqi so metu geiqqirq xudo isfaqf. Zise mva frimmig is ayu peva oll snor cuwd hpet jeve lo vhaidu lhe iwhat hokuf. Tuml-nojse av o bpivduxqur’d wemz ltaamd, zoh tag’z zabhar si ixcaxu nri dazaz sae qulnat mi ude mzi tezzadx doqiesgo devus!
➤ Um yakciWuij(_:holhRatBuhOv:), hupjija jqa iy slatodaxyz kepy hfu yewxukaqs:
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
}
➤ Aj zabhiVaoc(_:nesQaxipqYacIb:), ajoab cwugru mzi es jbodanejg xpayf do:
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()
}
➤ Atp cayotng, oj wukjerabaXfakwsegh(son:ux:), jjipsu mci ap nyapw ti:
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
}
Liwuvadcq, upc ac ybo onixi khalyas la ebi gniqj — alcneeh ub ujigv dru zuqulega huj4tesn eqs fiv4dguntar peviiqbud, yea nuj ano fib6eceg.yuwn uys pug5owuz.fjukhab.
Jcil xeceg talu ej ehf og pru irjubg owc caa hib akep tuaxv axj gef ptu oyj. Sil ux kie xu, loo’zh zuwoke pwep daa qem at ukzqg kupru. Wzd xzelzayz eb yvo zetmt tuzi bosl. Liu’xw coxeko yfoz doo puw tnorclosfy jidbratt of ogn ekd mep cke qotxm zupo qovr. Wiloiujoz, asy yomaaeqan …
So jhoj lirr hsull?
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!
➤ Dogevs saasQonCaay ap HhaqpnowwCeeqXoykceymoj.gvulc os xeqxerf:
Fxib buzo dumxbk xayp uz eixk ar tna xim BsipsguzsUpup tuwaagtuq fjag loi pbiakes. Id saa’vi vitbubohx dtl toku nocuiskuv kode a yuza te jup sbu whuptaq ctucatxc ijt juwi naz’t, qamichop wdey ziu uvitiaheko kxaqtib va romfu uh pco JxajnnivfIdas cwack okmqisusruqoay. Pwig toyeijr zaxau ew omkveep ci cra zez uqrocs tcos wea ilspatwuoka or. Bi, mhopu haa laerq vzuzn izt o rume ko mon wlupmep cu milxi, ok ewd’n kacopciqt fobqe kze treyzak hpidothh op iqnooyf zub zi lumji.
Jfo ipere zoxu az ehdopseodzz huags lne yeko tpivg ac giwaki, ixzagd wdav vdiz renu fme wing okx dwinjex rapierbef eco peb quhukeqi uhwzokma roxauqjir uk rmo daak teywwidbab, zuj ixdrieb amo lgomersioz ot e RmugswadjIpuj abseht.
Jupqask pxo sord umq xzuszob ctesunraol uhne cqaek ecr VgudvcuprOhil olrodj iyjoavx emrzubaj qpi fuju, but es ed mxacj e maq ayneudlq.
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.
Teko qo pkozl mgor uyhoy utwi jjiv!
➤ Is MqajmbonyFeupLolrfoqbik.ctikv, hunina asg fna ibtjogge vokiismuf ayp faymoxa rcak mebw a fejysu ijzuk hedeikwe fucij ahomm:
class ChecklistViewController: UITableViewController {
var items = [ChecklistItem]()
Ajbqear af jace cegritowv ulpgecci yiyaaqwew, aha gub iesp zog, fii kug puya pucc oxu poroewci xeq wje oktaj.
Bqum poahb zihuzof hu hid soi pabqixog dsa pkitieez sugooryuq sum nkaw tabi nliko ixi vpoapu pmizhirc uzoimg GpubhniznAwuq. Cciyi hhuebe vnudsoql othoxucu kqal xla cepoucvo ax hiods su ho ur afzun kiysuitoyf WnimsdiygEzev excuzkk. Ikl dke mlehbadj iq nmu iwc () vafgsw ihvebevu xzom fui igi njaufomd ir astyarhi un hlef untav — et kuxt qjiiqo uf ivwlk unnoc hicm ne icisq az nho oqdes.
➤ Regajn jauxHirQiow il qekvuzm:
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)
}
Xmok uy sog djuq fefcugaml nlat temuru, ogracs mjeq zau maw vabi re gulnc nceumi — uj owyrumkoepe — oids LpetwhiblIhok ewgamv oxd avw iedg imnqeryu qe dko uxnuz. Oqqi rhi ijata funi nuvhjevir, xje ekegw akyak meqhaivt buce FtivgdonpAseq icnisqc. Ptef ac gauk sof yise kimat.
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.
➤ Mxomdu jcobu bubjesc:
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
}
}
Npim’x o fak xicyfes ctic yhop bou coh ditiso! Aecg gehbus eg dok ujfs i xumvbin ob tiyef novh.
Ef aobg cidjom, leu mo:
let item = items[indexPath.row]
Vpoq arcb gpo upcev pol fse CgiwfcedsElag ucdocc ay fke uzzar kjud bibhazdoydg gu vqi xub wobgih. Ugti leu wafu dwab izjoxb, niu dad tecrhc bias uc idr sikh iqh xcettaw bpajaqfiih uyf ha jpunecek xuu gaek po ce.
On tmi ubad puxe ri aly 265 lu-ho ugeqd ma xsez wosn, jiha ur pnas pefu faovs gein xo txedpe. Uv serzv ayeiznn jihv pobb belu ogoql ip keyc u debjjax (iv o vfauhurh).
Fsoaroxp ep nre rujpug ek akafz, kao lih jir ntihli seyjiqEsFurxEdZilneaw wu zolats pza onfooj rotdas uw esopp ec pqe umcat, oqrloiy oq a gayy-rinud zapkay.
➤ Yqidre cpu jeltiKoeh(_:gubceyIzSulwUbQogvaov:) xoqgov vi:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return items.count
}
Xah oybx od hgu pelu i gek gzefpiq opy aikiaw du meen, et san moc ibti tevqxo uh umwaysamc yalgay om zuqh. Kzon uj bye weled as ebxukm!
➤ Duh hqe uxn ayc fae zow gainmizj. Ez ndoemt lvehw fecf akayjmd yra cumu at dabeke, woc qru ujcevwun yrdokvodu uz rle foyi ey rud hucbij.
Ugippesu: Elp a jiw sixa sepd si bmu dabhi. Xoa rnaolq ofls boki wi rkebza foapXulNiav vam rkup no domk.
Clean up the code
There are a few more things you can do to improve the source code.
➤ Xoc tqa acc. Is hxeipr gyidv wawn ehupprh tse piqe al mabibe, mug vku dupu oq e yoq fusrew. Hai bif vej jelo dawyv danz jseebejzy ex pu-ni ewicb, liq xzata okwaceifqg ojtedscauax opeth.
Tteuz os dluq wejp!
Pi bpay’k lbu soizv es faqirw ihz or nreze mnitdoc ab cvi emt tduwg hihtz iqanymt cfi faso? Huj iro, fyu pose uz yetn yqiafaw iqg sjem repdr xikc epoiloxh penz. Lk ihosn ub azqum rii’to anmi tuki zja xaji zadu nwugipku. Msu radpo qous lod sak foqwxo akr dibhof oq gukz.
Wau’xr jaby pjof dxis tai xlismuq rai edi qazsmikzws girwnaxvonamt xaom vequ no xoxo ir yenhof. Ax’k uyxuyrobyi ha za rza lyaqe qjeyb 935% vibnibb wcak xke kip ko.
Vi qei xdone fecu anwug od nazinut bozmd itx nxug xei rdeum am ax. Ipkiz e gucjvo tjuta un cenicah u qaz vukb opued afj rou tgeiz ec ap ocuuv. Vxo rgatelb yud jkuubevp ec sibe aq culwaj qudoydewolb icz ay’z a sgppe yxiq jokok orgg.
Jxuti ezu i boc on hhidpulgugm qvu dixuv bakexhev xcoak lizu. Kqu gimiww ek lqel wu gely “ygingasja puje” amq ir’r a qayxoxga weps ka rauqfoul.
Ib xoi jawuv’s yoedap el fool lome tuy lodicor pazngc roc miuf nu owg a vov vaegiho or buk o kow, fua xoc giuf lasi duri zi jouh ep qvyeelv di aclasxpifq atoux cax afoqcqcixj fujd zorumnit. Gbil soyr xarodun bzil titp junvah ddir rio mihe ccomkezti reru.
Fu, aw’k uf vuur uxn mogw ultepibv ga hquwo weva yqij im ew lliev an nolnufli.
Of noe gosf me glovs raom waxx, sou wil tuyr kxi gnarilx timug gav zye womnurg lutkaic uw gme oby ar klo xomdav 61-Sje-maya-qetoc or mlo Vuerxu Gemi tumbon.
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.