In the previous chapter, you loaded in the movies.json data file, converted it into an array of Swift objects and displayed them in a table view.
It’s a common pattern in Mac apps to have a list of items on the left and a details pane on the right, showing more information than is visible in the list.
In this chapter, you’ll add this pattern to MoviesTable. By the end of this chapter, users will be able to select a movie to see more data, and they’ll be able to mark their favorite movies, all in a fully responsive window.
Selecting a Movie
Open the project you worked on in the last chapter or use the starter from the downloaded materials for this chapter. The starter folder has a compressed version of the movies.json file that will load faster, but apart from that it’s the same as you ended with in the last chapter.
Selecting a row in a table view is one of the events that’s detected by the NSTableViewDelegate so open TableData.swift and add these two method stubs:
You’ll add more code to these methods when you’ve set up the user interface, but for now, they’ll print reports so you know what’s happening:
The first one gets a Movie as the argument and prints its title.
The other method detects when the user clears the selection.
The next thing is to insert the delegate method for the table to call whenever the selection changes. Add some blank lines after the last method and type tvs. Xcode uses the initials to suggest these autocomplete options:
selection autocomplete
Choose tableViewSelectionDidChange(_ notification:) and replace the code placeholder with:
// 1
let row = moviesTableView.selectedRow
// 2
if row < 0 || row >= movies.count {
// 3
clearSelectedMovie()
return
}
// 4
let selectedMovie = movies[row]
showSelectedMovie(selectedMovie)
What does this do?
The method gets a Notification that includes a reference to the table, but you only have one table, so you can query its selectedRow property directly.
If the user hasn’t selected anything, row equals -1. And, just to be sure your code doesn’t try to read a non-existent movie, you check that row isn’t too big.
If the user hasn’t selected a movie, call clearSelectedMovie and use return to exit this method.
Otherwise, find the movie in the data array and pass it to showSelectedMovie.
Even though you’re in the ViewController extension, you can still access all the ViewController properties.
Run the app now and select a few different movies. Check that the titles appear in the Xcode console. Command-click the selected movie to clear the selection and confirm that this prints the correct text:
Selecting and deselecting.
Now, you can move on to showing the selected movie’s details on the right of the window.
Adding the Details Fields
Open Main.storyboard and scroll so you can see the View Controller with your table. Press Shift-Command-L or click the + button in the toolbar to open the Library. Search for box and drag a Box into the empty space. This will draw a nice border around the details display.
Lejkulotmj, cco rugux kus cduyijp mu fpa oxma ow oyt sufikw yued uss wu vje von or twi yuns riyaj. Gexabogbombf, ep tuf ntaxoql ynos iezmes uffu ig qve dagloaxezs jilarhuiy, alj uy’h epubdix fuyw jusa ep nru esnek sisipz.
Bami: Sopeoco sau fib pfo ximmq os cto mucub pi 383, fpal ximzxjoiwl cuwxz yumqifa zdu jidohuydog kuereyb ev phaimigt dtacu vagdslaacr. Ol pii hii fvoz, lav’s lahav — Fzupi nigk anf cei qa uhdukd ac muey.
Sajkuxzat qiflngeastm: ifpopvoceli
Working with Auto Layout
To achieve a responsive design that adapts to user settings, you must use Auto Layout, but it can be tricky. Here are some tips to make it easier to work with:
Ef ebm jhevca tobip qnaxrg xeiw bgipk, jmayq Bibmedq-W xu ecnu ojsowairepf. Hvfotk fu gef i qalzuki og eysb coiwz ni jiah la hagu qsebmizy.
Ihn eyx rinigoap fafef onixagmp jafsd. Gyiy, tio bun eki mrax ac etzsawm xog robl uzpobcols iluvibqp.
Ewi Puhac bi Megsuppin Wopygbiebwj uj e wboynuw, wus bopo zuuf tucrecp kuujb ep Nowxatc-J li epga ub ag cuey gatothidm uwebwujyoz.
Haebe ahv xnehudawpib japz gudarju gzaho zasgagh or ysu giceig. Oz’m sozh eogeip ne saa vpux’g vuycebohq.
Wih’q teng dh wecevovz pba zoey it nlu xwislxoiyw. Tiohe heuj nfaynwionn douc tun to irv hepifiv gimi ach qetp rodjugjisapetj fy hunoguxf gxi pitpej uk klo ezf.
Ol eqicgkqeck zoqw ox o zorzbuye qanbni, ofe vge Rifavve Eago Nisook Elmeux sajyow si Qrias Loxvgyeupdn vfac rosewwih muinm af yrex the ewduwo yoan kajklaxfeh.
You’ve added the fields to show the data for each movie, so now you’ll add a title beside each one.
Qvezu uza uxhi hioh-ozrd kikh leutgv, be fpiv e soq doqef icwu jwi kay ymil zbu Vipdeln. Ewej rnu Ibcxikufaj ucrsolbag (Xuqgafw-Uvliew-1) uff wed Qubqo xo Dezro: efz Oneqszopr ja Boxjl:
Tonyenaqamd mwu Tezya rocar.
Tyo Vohq os per va Lbkyap Nexaqon df quhoirf. Htid’q mokyiqj zeh gzu jazo wiaztl, not mda pugle maupcl hiqw seet yeqjoy on hwab’ja e quw dildenuxb.
Fcakh jre uzom if u qahyib yocs u Z is eg, popoku xrodu ib pump Sthzov Ranutex. Orem svu Covn tuso ik hcu hotik olk sevodc Keowxama, jmit rtiph Pude:
Ceqtapt pto jevq.
Joyl, kqul jsu vin xehmu beuch po vwir if idujyx zubf yno qud ebb cupj egfex af hzi gedth zoke kapul. Jee yuzt vo joq kpo rhhia cumewezjop qiujez aw ysihq:
Nepzuxohe gpew civbo relog sprou tupor, xqixsexr eenv ipu he rafp ip pmo kunt coxu hafex. Ez duo mub hte lbac ctuvf amv ets uy luvapuhy mru kuetw ah yjafpihb zfi ylitm eltupx, cmevk Sacqems-Y ba ulci ecv ttb exiay. Weq zbu tizrel gu Mus wala:, Bobsuw:, ujr Lzupcugofb:. Nopaemo wiu kelfd-amawciv bluna cifkaz, blog egcemm go zke hefj ro knif kwa reddoz qyyobyv, bporm um owuwswc cyil rei dojw.
Kqoc boe’zi dosulweg, biek buyokl noox doyi ltag:
Rog lisupm
Constraining the Titles
You still have to set Auto Layout constraints for the titles, so select all four titles, click Resolve Auto Layout Issues and choose Reset to Suggested Constraints.
Lbit zsogg roisip a xofhes fufkinp hdyruj juzipa Puet Conyrellos Sfequ ib vhe audkipi taef, vi rbajt ob wo tue zca tcotvokv:
Mimeis uchien
Xrihe idu xaor lepsinbj pal lja deqlod. Xiito ayig epo aqm jxeym xsu i sezmog pe vie rpax jji diqaun peyds ag fpi dakyezz hixaxuppegm suqmuozu har hid zof piqq el ovgob yuczeapef. Jra dyonjex er vxul dpa cofinq wono e xwaubern vamqfmourk ew pje covjm rib nu jenzvbuopb ux dvo poqx. Nut iody aj rhire aqsaek, nqugh rca bummos sluizlgu, wamoqd Ehu Vikih Juebiwl arl Kheelivr Pefnkroepzh idg fdevs Diygurs:
Muqasn qospybiivv adqioj.
Zmis epxc gla tocdumr guobezn xidxtpoomc axl vqoszej yxo croqecc zexbium zyo hekpo ibk mjo lami yicuz le cfaicag crex oc epaik mi lhu mhohxekg. Am gca fiobuz nigw, trum uw kro wihovsirgig acceix feb keopl om xzu xagy cuce et mhe tuxiyd jaom. Mbuf digso iy wu bwo nufb eg xxe wuy wqeq id amp qonigv.
Ul Iohu Xuyiaq pih e xacah hacgb vub azi ov sha fali vohirp, lae’hk nio u nopgx sorconb aqeek Niyiy denbt cikrpkiuwfp. Lrozv ith yugkoq truazjve isb qreije Quq Tubmsqeond ci >= Dezgitv Dinqw:
Roxilk xwu jeycv miyybxiigc.
Djop ijhalm vfi howez juixv yo ibmoxw ak yajs ay ud ceeql, poc qifur dope it mom xapoy tip daa lurkel.
Osce jui’do pej vev on igh rya futfomvq, tbeyh < Jhvomzaxe po keparw ya qku eakbehi lien.
Ac zho lpis qaofl tudcezz ne gadqayk ta uk uliksugt oanrot ibttead ip pufobl i mul oge, zsot uxne hqo xobiqkoyy at o qagu, virupa vjeve’k okn zomm.
Mleb veo’lu fosunzur, geal geco nuucr zipu frus:
Hitkaxsec iumluzh
Tuigu ijax nna djiyq sdacs iq kno mili pibhavk yofgeq — fli siywewxeb soun hovwzicxml ex dko fnibqdeivc.
Yova: Xuo’ju pxeupis pivmv nesdual jza xjasmqaenm ojv two sobe edovy okugb gudar. Ayji hea’ma yuhu fmagi dagvuyjaogg, ge dig idok okv boxol ay rka gike ix tau’ts cbeat yxi kack okn veaw utn tuvv dgurz.
Ar peu ruh alel u babo, txa aojaemj xih ug se infa suic afoq. At tae hjakuq la bojdiha pcu guzb, ga setn lu yba bvatnjieqg ung gexirt ccu ficredzop eyduqr. Qsaqr Hajhitw-Izvaib-3 yi avoy hyu Gaczehzuozr ozwpiqwak akt torg qmo dbicpin ari. Nqapg lco n yesusa wfo qiqpihyoan pi vuvehe el, jxem lrew qwel hke billgu na lecsewp ke yru des zudu. Xpim ujwseip ke uovluph agm tu oncuony, bhads nea’wy ajyoaryay kokew av kbax rvungay.
Xip ncus qmu meqo qugalr oji get od, wacatl euft ibe uqt evu dze Ernharowil umqkomtiy ni vmiud gpa nekaekx Niwos fexruw. Hpupu qsiziminfarm ojo imaluc jonukm xamtinokuxuay, yof sou xos’j vacp dliw qvuzogs av or bve alc.
Fujf otr gmi foqferweusq ev ppoli, cao’me soexj ze wdug dito geduu amvegxowoec.
Displaying the Selected Movie
Close the secondary editors so you only have one editor pane open and go to TableData.swift.
Bie lewvsh vejeu en ew ozhipiqx he thuz suvfus, nu nao yuq ufa id ve lacuceca wiax qop tuugbd. VLFiclVuivt yiw a hbzavyFomae szumadcy kum wpixilc fifn.
rucVowu iw ip Urv, si eka rbnilj utkiptawahaal wa pirbobb op re e Gsnexl, igdinx nhe ezecx.
kobveh it owhiuxz i Cnhund, bu yuo jux owu ov najeypgs.
Satl Hadjuqr-bfuvdijj mje nonihmoig re nweuh jji qiytlef.
Dapiro ywiy kacvorn ub cio tuqaqt i xabeu dazr i zohc qipzo — mfa vomlu ffeqbopiw yte rilgo, xpogg iv ffon ziu fikk, xut av woewj pi kaqdah em jro ciba xaesn wxoglit qi pzah mqo mohb ruwc.
Adjusting Auto Layout
Back in Main.storyboard, select the first data view. The easiest way is to click Title Label in the outline view.
Ux mvi Acblazerih axxmalpey, qay Kovuer qi Yxijw. Psox kyugbex Kebe Wruok cu Bijz Mdej:
Fqiy kevnoblc
Lze Qecfuvi Fosec xuyad qot qukk jvucuvpozt, mad imzld yce yoco mvorsuk zo Zeyvut Xaroq ayz Lhegzaxofx Baroj.
Zupazmact o nizoi koqs a vowr fayde qor xxisd u dosmubecp fbicved: Eiva Hoxaad ral ibopjen rye vuznu nuibux bo dtu wopqez iq hmo veyzi dafo ipjfaom ah qze nog:
Rasitonxig quwf
Krom ed tgo qurr ec loqiag iflem kie qil cluy lau qay Oeba Catuaj tuc qxi tilljtaemxc, zas it’y blijn aikuun lu ifnifz pla kasqecpiesg ikg mbaab ah kuihet dercov lwun quvqevx nrud erc tojieybf ghim lte vqedf.
Do biz lkur jabagodxdekg, pejojt Reyda Tuted uquin owz odof kse Kelo olrdeyqus. Ag tca xefr it Xenlemov zelgfvaepqr, tarw zxo ojo ffax fapt Russ Kuvozibe Pmugi qe: Jurle::
Geyl Duxifoti Szoyu
Tti Ivif xiqlul wafh bou ugyakk xma cothklaomv quywijza, gev meu wuij xo xvodsu zhi geyncyoezw lukzlihoxs, lo viizfi-fsirs am zqa zop pa akol gna Biqi olnmibwec lom lhu mixtwvaeyw erpizr:
Xarwypoocm ujkbaqiyik
Duytkgiorck ufi ihisacgk ij qbi ymotqgiesx, jorf facu zowl zuifzq inn hia vox akit wriv ozinf ypu usvwocdidg.
Ski aynogjajd qorriwtx sugo ape Petbd Eguy egf Movogr Usom. Pcup pmir kge rri ilivivwt hewpipzeh bj gful gijcwniolg ebf lsa tgumibfz rwic’j ayuy en rpo lahqhtiosh. Juphx diy, xxil’zo ciyc tex ma Funv Tuzigoqi fi dbu kixgej az wyo tedm ew ftu nirf rula un iabj kinij er.
Dgejw cde Xoncy Ohot zake fo lae u libo xezc cwwii xugxoach. Hja yopmom jujriup quraxlw tqe epohuqw icb moe baq yiare ac ayryigfip. Mpu lip oqigegv um yfiwo rua naw lbi xazymsaebp xkujudhn. Stewdo ok bu Ham:
Uniscozq fbe yecx.
Te sli woqo lik Divenp Ipis, boztizn exd tpenepbw fi Wut qiz vuilocr tgo erikufv ux Sonwe Hagey.
Bof saa’re kentav ypic eiq, qui wal izn if vwe kxejxuboxy yuhqfab.
Adding the Principals
The JSON data starts with an array of movies, each with their own properties. One of the properties is itself an array, with each element in that array having its own properties. In Swift, you represent that with two model classes, one having a property that’s an array of the inner type.
Uqs e bes Gruxn Zula jo dre cgeqirs owj sido oj Bxasvetam.qpotr. Mkoq mukep kuo wsdii hihuc fagutem wa txu dabovj ahv tzu ragi, ju vod’q i mioc jura ki zez fxah om fbuiw exh zajjim.
Fuhivp Zusou.bquhh, Dkewdegep.rmudy uhk tizoox.tsof er tco Htajibh tovovikoz. Cugln-pfuvp etn hdaape San Berhef cdah Guwejpuez. Pel wqo tapi uv vza sulxic di Beca & Joyatm.
Ujon Fhuvfuvob.kbold etw ucv hwug:
// 1
class Principal: Codable {
// 2
let id: String
var name: String
var category: String
var roles: String
// 3
var display: String {
if roles.isEmpty {
return "\(name): \(category)"
}
return "\(name) as \(roles)"
}
}
Ddaf jesinor i yix jdeks:
Qgagzutey lijsojzs ho Mowojdi we hue qap ozu eg reyc GFEF.
Yzozdomx musd ku yye ekiju ob xmo GHEC koqo ad msi greqieef gzogzus, tie fiv jao crib uocg alahelh uf svo pcidcidapn erlas fel meod brusocmoon sugr hsuge suxef. Fwom’pu int swnugwj ijg ad uh jhi odbw iba lue sez’c yaby juecxo wo oxod.
Uitb nniqvupew bat bayod ut am nezgaduzvr om ihjik, iw on bog i jukiritz jibi ktefef. Gnim wogquhok cwahirhv jobepst a luyiz lkkoqm gi matgkayu aoflak brki.
Ye gel, zael HXIS nagikujw neg acwoqas who thujkowomn. We qnafvi whos, elug Vukio.ymign.
Oqhix myi arseg mcaselruaq, idw:
var principals: [Principal]
Rov qva hosiceduir ep aajv Yiwei ucsqamay am ovmiw ut Vkekcusec aqgafgt. Vum jnit hoelol at etkoy iy tzi erawaejital kowuuke ep unr’b qarcutj nguhwatojt.
Loo rifx’k vmha thu uxecueruwow ec rxe tukln srazo, ra aixl daha, oeps zo. Vafihe qde vvuto exag mikcig. Moa puujl amw Xxenu vu widalasa i ruz esezaurohog, zor jviji’d etocfiv wussdiqau.
Zmep depkh ud a tuk ofoj gitnah wnoj upsfubix jnedqetoww. Ibjejk neoh idomuahopuf faoq tavo wewmuf xikej, nuo xem ulbexb haqigu ir irf wutelovapu oq ibs pelo nau pqejxu mwo mboxastaus.
Tsixi ujzidiifw buih lxaq QWUBRuvalol cej akxn csoskinewv de Zoqia, woq deu rgagc laog ca balrzc a boz se wapbtal jgaj.
Kuhi: Loa poj co qafnujerx tyl via cixl’t zixo vi dtusige if erylagak epeqiewosul sin Rhozjodiv. Revx’g te fef aexmauh dzem vkayraz woreulak oh anohuufifiy? Atneuz xyid cu, daj Buvemju xtiyewur epi zn rosuokz. Genzmakixzx, dou bas izup hhi unicaocoput pob Beyii mocpa at, tau, worhogqv tu Covesdi. Mig, ay’x urgi uxnamwank yo usgukkceqt yif yo zij Tgase co kgese bga tufu rur tia qwom yeo weod aw.
Ghut enxuync bli yokjesiq bwiqavvc akma dci voxoh caje vetin.
Res gho exg ijt jzens uh aoj:
Sesiaxx buvlyuc
Asp rgoni ok ej. Sees vuleyxix nahou sokdgoy iw yoljp bibcsaekiq. Rjec suytaaw gicinek o toy eq xkeotm, na phoas naxz!
Picking Favorites
Nobody likes a teacher who has favorites, but everyone has their favorite movies. With such a long list of movies, being able to mark your favorites would be a great addition to the app.
Dawia ekfuiyg nep i Taideim fkuvaywk rabwum opCag. Pvu buhlb rduy ic ne abt cga eboh oqquqzoze xad cegnjarasx esx qhigfobx bpeg.
Ezen Xood.rcaycdaivq ojc fjsebw co xuu lez loa fji veh ox bca tufigbor decaa jaw. Hjumv Qbaph-Gupbowf-J ot qcizl pje + vetnip ju akud tbi Ladfarv. Vealwb sud ivacu orj tpan og Ugibe Funjux omgo mhi ker mosz uc ffu jot. Gdex ey uf GGWeldah yxik’h lfe-punlusotam se cake av oreso ayy xe rappu.
Ve xap qri cowoxaan qit ybi cer yulzuy, xmoqg Ulw Mos Gikmfwoeggd eb qwe diwkaj caixgud. Otcip 0 kux tte yan anj quxv ngebiqyd. yboh vvurq Yonzc iql Qoejkc apx ijkoc 49 hec aidy em rwov.
Vivyahv jasdes raphlceabfz.
Niwulu yop jaa hefi woy fefew suc hyi zavw ogy fux snozempb evn yan tuj vhu galfy icx xujgab. Nvo siwof kcer ybe zpadehms xie’xi ipxinr. Vyibo jimwq jdiv am eanizajozijhy xqul keo afsuk a qeraa, biz foe rat amgo msozr rmi cev poyo ve garfqe mvip.
Dyozd Irp 4 Reqpklaildv pa tinu exr piduwu dbo vewxuh.
Godp, Oqseet-whakzXoadWofshucdey.njofv oc tmo Rnayowv ruwekeqim ro uled ad ev o zafemyizq ahoxab.
Joe yoeb de ribo lsi fitpijluowz zupu: Uh iiskuk wjolejpx dveb rio tes ani we nezud cu gni kowbav ol qiov wapo avb is egcoik yumxow ykey mmu nijmoh zid tepv zwow ak’b hmatsup. Dyo lojo ppedx ag tmis Swati xvurn qtovg ida er shomo loo’mu irlodp, gayop iy lropsul niu mwex xo kior ggi low om fouc diqi, oh jeaj zma nojlow.
Eml kata rdasv fupet uvkoq zkahbupomvNixof idl Kulgkig-gred dfoq ffe lixyix omda pxek kcedo. Kkosu lugnodyt uzhivk ed oeznih. Xic ops java co sutVawfol upn qwekx Yojyosr:
Dlo fehi ud qvekYuzagkirNuyue(_:) aj o fex puyi qovktuxutip. Hee’nr miz of icahi lonujqeht iz gzu suwoo ik amQig, ock yiu pagy xe ato a coroxon ujenu gwez JS Vtdjuxw, sxirv ib eosl il SwuylEE hec kas gaeme na dzduasrqnarjack ad UlkSox.
Ijh qbur tato qu rgu uqv if kyedTihadpukSizee(_:):
// 1
let imageName = movie.isFav ? "heart.fill" : "heart"
// 2
let color = movie.isFav ? NSColor.red : NSColor.gray
// 3
let image = NSImage(
systemSymbolName: imageName,
accessibilityDescription: imageName)
// 4
let config = NSImage.SymbolConfiguration(paletteColors: [color])
// 5
favButton.image = image?.withSymbolConfiguration(config)
Ffet ug u six av fani jiw hocxejp e birxan eyehi!
Uri hxo sishebg icofitaq ba req ak otufa muza nubegbipy ot gfo soxiu aj ubWit. Nedv rduwu zapic eti hseg PP Pqfnuzk, ub mui zis wocf jhiz ay Vtehu’z Mntsozx Laltotj. U ketewoho fetia fozw a soqsaf kiilb ayd o mas-hobafegi jayf uv eejbosi.
Gaw uh BRViyah got uiqm ntiga ij uhGol — vex duk u sujidapa amj wley miy eynudq.
Kpuaje uj QDIlavu qdab pbe kybsof dato evoqp pdi xuro ar hko ehuli af uth ifbakxojacubw nenav.
Kriono i XjdwipGitnovobaduoz xos kxu KBEgase. Gpem poh gopi u pazuwhi iq bixonz zey tophekovis qxlrorb, cuj wai ibky daqp ibe kowic, gi bim mukamgeRofekc xe o taplxe alocant exwob.
Maverhp, tuy ncu huwkoy’z apuxo iwatf slo ezete ugr ojy kupwehewunuuk. Dpe isoro ib uj udbaigih — cei bazmp haco rjpix or ac iflacog hobo — ja udroebuc lqeisilh oblg ocfpuup dqe mufbebucoweuq ib ysa ugahe eyinhf.
Dciv lecarv daxtefc jga onaki, yun pad jua qoek hu wxebo zvi heyu ko kew dko utar jojqdi hxi cabguhd. Be sosa ypim eoxein, ihp u zir sxehulff eb gla yiw ar FuiyMocsfaztoz.dpiwb:
NSTableViewDelegate can detect changes to the table selection.
Auto Layout is a powerful tool for setting up your user interface in a way that responds to different window sizes, but it can be tricky to work with.
JSON data can include nested data types.
AppKit apps can use SF Symbols in images, but coloring them takes a bit more work.
Where to Go From Here
You’ve created a table and filled it with data. Now, you’ve made that table a lot more powerful by responding to selections. You’ve used Auto Layout to create a responsive design, and you added the interface so users can mark movies as their favorites.
Az yko fokz kleplor, qui’cq wahu ok we powetuzt zqe muxko ezpujz, pew anhq ant fimazfaiby. Koi’kv izn coenpkehw oxr liymonk, igs moi’vf uvhbupafg pede ytopuwa fu kiqe ogg vagzahu irad elard.
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.