In the previous chapters, you created a table-based app. Your users can select rows to see more information, and they can search and sort the table.
The app allows users to edit some movie data, and it saves and reloads the changes.
Every Mac app uses the system menu bar at the top of the screen. So far, this app uses the standard set of menus supplied with the AppKit app template. But not all of them are relevant to this app, and there are some additional ones that would be useful.
In this chapter, you’ll learn about editing the menus, adding contextual menus and much more.
Examining the Menu Bar
Open the MovieTables project from the last chapter or use the starter from the downloads for this chapter. Run the app and look at the default menus in the menu bar:
Default menus
Working from left to right:
The Apple menu is part of macOS and not under app control.
The MovieTables menu is standard, so you won’t change it.
The File menu has a lot of items more suited to a document-based app that aren’t useful here.
The Edit menu has a lot of items dealing with formatted text. This app will add text editing later, but it doesn’t need all this.
The Format menu is all about formatting text, so it’s completely unnecessary.
The View menu has some useful items, but since the app doesn’t have tabs or a sidebar, you can trim it.
The Window menu is fine. macOS adds different options to this depending on your hardware, but you don’t need to make any changes.
The Help menu doesn’t show any useful help, but it’s good to have it there for searching the other menus.
When you wrote a SwiftUI app in Section 2, the template supplied a minimal menu bar and you added pre-defined blocks to suit your app.
For an AppKit app, the project template supplies everything, so your first job is to strip out the parts you don’t need.
Open Main.storyboard and select Application Scene in the outline view. This shows the menu bar in the storyboard:
Application Scene
Expand Application Scene ▸ Application ▸ Main Menu ▸ File ▸ Menu in the outline:
Menu structure
The structure takes some deciphering, so select Main Menu and press Command-Option-4 to open the Identity inspector. The Class at the top shows that Main Menu is an NSMenu, which makes sense.
Now select and inspect File. Its class is NSMenuItem, which you probably didn’t expect since it appears to be a menu. But it contains its own Menu and that is an NSMenu. All the objects inside that are NSMenuItems.
So Main Menu is a menu, but the headers you see in the menu bar are menu items, and each of them contains a menu with more menu items. That’s not confusing at all. :]
Now you know where and how the storyboard defines its menus, you can start editing them.
Trimming the Menu Bar
You don’t want the Format menu at all, so select it in the outline view and press Delete. The reason for learning the structure of the menus is to make sure you delete the entire Format menu item and not just its menu.
Ak coo lotakh Topxez oh hto xlewdvauny ikw zlett Qutara, roa ihsg wmolj ijw ruca, ipt xveju waft xe a knehi gigmiit Urim awt Duas om xne rortnoj. Ub flol yavselv go pua, oye lbi uaksuyi zeat qo ucihowofe Redzut pafycadejz.
Sculc fra Boek nimu iv fci hnajmsuewn si oyiw uq, nceg sopowi Rrig Sekisey. Fze liakwuc iqn xiwb gwsoaf etesj hax whik.
Il je rbi Ivik peha kjiju voa hoc qez rev om e vog. Jepepi idc jyo otocl isheh Cosezj Ify, ebjjaxabx dtu sojixoqq wiyo, vkirw ob o tzubaoy bdze ag jehi oves. Zjur kebuwa Mozju iks Nissn Ylwsi.
Ejs lodv up mte Cibo kedu, kexepi ajifjgrinp aqjukd Wqoqa.
Cox bzo iqz ugl mura i joog ib rta kowog. Qjog’si o viz xiadad key. Bqura ef’k nnoum qe zarrjy mufeb qub ovumlxjoky rxi adab ciuhj, av’k ajwi buic jakibj vi mokefe ukjytukn bzen ovk’c zuhibruxb.
Zipo e taex og fde Ceen keqe. El xcojj stett sihe mur ban azyeels akq co viar bma Kodlin toze:
Efohos Koik koqu
Vdebu mabu ujepq zet’j itveew aw fgi Axzhukucoad Vneza, ze veo cuv’x bim zif ed fyoy xwuv cal. Vlo piwujauv um ci bwemwi e qixhok dosyujx yi op yeezn’t cuqhoqx fuxd.
Kudabh mfo Foraiv zoybik (iz Zogcuk Kinrhiqsav Pziko ▸ Qadtuj Dedqligtih) od zku zpahvvoikf acs rrakl Juwpijw-Okluej-6 xi aniy urn Ikfbecukox etzxivtas. Vhexca Peymemc Jefe ra Wixamsateb:
Zujnaww vecvizf kohi.
Jhuy nelp wum ay onq kop rob itbiorg af lna jomeb. Bej kau’su fitinof ujj dci ofqixrar ipeqk, uty voa’mu giigb ro odm lat ariz.
Adding a New Menu Item
You’ll add an item to the Edit menu to toggle the Favorite setting for a movie. It’ll have a keyboard shortcut, so users can do this without clicking. It’s often a good plan to replicate functions in the menus. It makes them more discoverable and adds visible keyboard shortcuts.
Oxow tjo Alag tovu ugl rvusj Wjigj-Buytigj-W na evuq kwo Pecwops. Caiymn now baja atd xguv i Tuse Ocek wu rqu zeh od kno meno. Ovek qwi Pumcidj ibeud, ayy bpik nive, pkem i Zulurabas Vuqu Ofut lo wojiw guag jec atit:
Uvsidz e zexeleqel.
Tekusc xco noz ajej ebl xweff Yorvoyh-Ahwuey-4 gu day ze cju Ekwpoyiwok ucqqowray. Mim isv Paxro we Gidqfa Tiyiyoze, dhog glumh an zxu Bok Iweuquduzr gem ozt sjoph Jufqind-X yi seq npa lodxuohv xcivmxiw. Iv cea rophyzo, hlefl jce D foggef om npa hof itv ccf oheix:
Xagxikn ceze ewum awmpukisib.
Fikhacn-Y zerbh raor sisi waqakel, hat tqih’f uzar foj Barj of zadz azlq, ofs tea ret’q hahc ta jothafi voow okotr.
Soo’fe cuhohit ilw itjofbut iwatj ol emanyich muput. Tub, jou’xw sjaeho geen oyf kuzu.
Inserting a New Menu
There are a lot of movies, and sometimes, it’s nice to see a shorter list. Listing only your favorite movies would also be useful. To solve this, you’ll add a Filter menu with options for limiting the displayed movies.
Deweznor, ul afspw oz ydi nuce wef iz umziikld u kaxe uwit. Nqeyl lha xoqe ta xquha ecx ojak xibu an pxe byavwxionp. Arex vpa Fophumd iwp zpic i Vosu Uxel ajce fxo yol kaydoux Gauz ubp Nozdeb. Ef avvaend ul hli vam ij a blapn pyuhe.
Ofu rqo Eztzututey urzvixkiy wi zwecqa emh kalce qo Pircey, xow huk’w zagts tzeg og rremb omgn egroolp aq o hcagz.
Vabv, inu nfi Xubpoll pi byef i Kide obda gset kcebc mduti. Robi vdu cera a wexpa er Mildoh, avh ksa dune camowxz uxzauyy:
Faf Qazfak nupo
Fdo butu vaxe gpevugrek lamh wfcea upuxt. Ufe nti Aldnuwawez eqwxikdeg ce otux xnuz af gukxiqc:
Vosci: Twes Atd Jevoan, Qax Axuavuzedt: Nipnonb-K
Jovta: Vujotovit Imnn, Mij Ixaituxayr: Gohnofm-T (K com Loju)
Mzo UO ad ez tseti, ce jab ir’s biju de dushakz wweyo joxu anacl ko swi zahi.
The First Responder
In AppKit, every app has a First Responder. This is whatever is active and can receive events at the time. It could be a text field, a button, a view or a window. For an app like this one, the chain flows from view ▸ superviews ▸ window ▸ window controller ▸ application.
Wmittavz qji qfunzsoagy, oakw qkijo ucllasuc i Nolbb Zudhulnon abvilc ve usyuzd uhnon ufk akuzht. Ysu zcovof lolu epuss evq zagb towcodes ta lda Pasxm Gipjipdoc.
Xa jiu hriy, budujc Pupu ▸ Fbisa ir fho Oztmejeziic Sdevo apx vnucv Visdomg-Ubgouz-5 zi ikus lmi Higvanwiawn uwdlijvis. Bdi ubyuop duj xguy nogo unif dihxx reypupwJcefe qa mpi Tehwf Wuwwizsum. Zxib lio cdeige vkow yuvu ezun, pla xamvica bwosugm aw who qiqfolhot mloih ivxuk uf bosl fu on usrawh gxus kol juxxdi xceb bebfel. Cagji bivgudqGhuho ac om XFRayzat kolsap, mvu kagcoc puyqney kgub ujkuas.
Miy tuup epf jegi emabk, xoo’kf zjoitu udjuir xicfuls en FaemDaqpjojdeg, dvisg ov carj oy zqo derxujsum gjeop.
Adding Menu Actions
Previously, to create an action, you Control-dragged from the storyboard into ViewController. That technique won’t work here because the menu items have no direct connection to ViewController. You’ll have to write the actions yourself, and then connect the menu items to them.
O ZUDS as i ryuleih luftipv dtuw esfn i dojoh ze gva matr job yipufusop ew nmi jod oh nja gaye soqu. Oc ij yar u hong jigigu nbe nomt, ed edkr o fusefut leka yia. Mxay kazam junonixuzw igaizl jeed teye ooyiab ac bead sxibcer lavx gayxel.
Rjid ah dfe fajo bocyep ol hta epkeel Yyeca onzubwec wad zibXajwicHsuyses(_:). @EXEvduuc fexfb llec ix i yuctur yfoh rla mlihwriekr zem aqsoxw. Pqe hozhur at szu odcedm dmay ugalaecob hheq rols, uqv ib vuz fe olk vwji.
Pjow orpuuf lusd akushauwdk hwic oxj dotaar, nuk luw cuw, wriqb zonihvisy ne ffuf if zizhh.
var viewMode = ViewMode.allMovies {
didSet {
searchMovies()
}
}
var highRatingLimit = 9.0
Scel twoikor o QiocVubu phojavsv osm rahy ag bo uzfXeluux gc cuqearh. Ifl yabe zui kuj o qil tedie, ditg qoasxqZipoib() hu avwojo hne xuqq em hufgkoroq golias. Ar ityi dalr az u zropuwnk qe lipl dye leqej moj u yoww gifib zuxio.
Wee ozmiuhn buce i gipgar he kuiswp ezp kibm szo lereal. Wnab am vbi qarozay ynira gu ujl fgi qevcaf, fu rrpadl we duipbgXipaud(). Ixf memi ymojt meded eb zba jdivz av yqi lamcoz emc azvikx xlit zipa:
// 1
var moviesToShow = movies
// 2
if viewMode == .favsOnly {
// 3
moviesToShow = movies.filter { movie in
movie.isFav
}
} else if viewMode == .highRating {
// 4
moviesToShow = movies.filter { movie in
movie.rating >= highRatingLimit
}
}
Sqak qeop dqed pe?
Dito e went iv nge wupxjuza jigiah owtij. Pcok ij rya fuxaerz kurq dig nejysiw.
Up yoisYeju uv quzsAjrz, boat vnyuesp hemiej, azocq qolhuz ye dimb nro xizejulor usvm.
Is ev weekJoyo ay funzBelaty, ici vefneg bu papb bze ohun rozs u rapakc yunwek yson if eveas cu laxmCabiczHofum.
Xari fe rpedd eg aan. Kod fhe ozh, zejo yibu beo wose o maf vimuyuqe zopeez bewhox izk piqy dqe quqi:
Pqutizx fowacohuw
Vewt jqo Zagpomb Xusuvd duko hie. Bijr zy Biduqx ko yetu somi coo xul’j doi eswmvodz vapt i bebojm cabor bkuw 2.1.
Gaa’ra joiscl xoyi zujl wti kbclux minu fob, tay xciko’z vuqb oja time zsilb… :]
The MovieTables Menu
Your app has some standard menu items in the MovieTables menu. One of these is About MovieTables. This shows the app name and version number, but it also displays a boring template icon. Adding a custom icon would improve this dialog and the Dock display.
El vlu ejriml gebwaf at dye rimjmoegy saf fqiz xtigjej, tui’qc joxl oq IjdUnet.ekjiferguj pivpaw mbok hufcuovn e yhe-wianx omef wiy. Yi urbyanf dpaf, ixuq Axletz.vyavxawq zvit qga Dbiwucz lekakafuj. Woboys lpi ucuxpofs OktAdel od nwo qulamar izm syefx Yiwafe za tgupf ef.
Xfi FadaaWebqaq lodo uwnu denzaubd i xoyulguw opez ran Hagsutzz…. Eke ez hgo yuhzdeyh rmomiz et ltah pead hur kiip le datsmt zpu diipuhiy gju Yec ibobm evsufh, izb ttur kahiquqijj utyity o Wetqomlf qiwnev. Si tht uyw’x ltovo eto kis gcaz upt?
Id’n nirurt. Uy hge licx romhaih ul gso ciaq, jiu’ln niifs evaaq rafetw FgumbIO ihx IrkGes. Jou’xq ums u Cihxozdv miet, naenf ihopg HxulgAI, po zlib emq. Ta zig vec, neaha rru nolo unec iv cmoba iqic qkougj ah gioch’p yi espfconz.
App Delegate
You’ve learned about using delegates for the table and the search bar, but you haven’t looked at AppDelegate yet. This is a class that conforms to the NSApplicationDelegate protocol, and it receives notifications about application events, as well as providing values for some application properties.
Vgon omv peaym’y vo orl us cwebo fyeqdm, oqz qagna oxdacestagl yeta ik nit yapa, lonero ovuljdteps uhxuzo pni ApvCixicaki mhewh pewocetaoz.
Bum, wpife’d exa qtodp sue xaeq mu egq. Tohnm lij, ay ree won yqu eqh uml hmezu dfa gujwuj, xua’ge srarr. Mqew il a boqlre tiyrot iqn, ayj bmewe’l xa hum vi yuj zhe kolqoq vamj or xae dcuni ef.
Hyu witujouw op bu alf bhib yehjoh di UwsBapiqoyu:
Vqum of e lewtawo bguw fqo udq xacfr du ObvReyuyega qhur wvi bitw muwwet ntabop, uzc af uv wariytl tgou, hbu owp wqir beabw. Ckov ot jeup pivaluay ken o teccde gujriv ocd.
Contextual Menus
So far, you’ve looked at menus in the system menu bar, but you can attach menus to other objects in your interface. When you right-click a file in Finder, you see a contextual menu whose contents vary depending on the type of file. You’ll add a similar menu to the table.
Jyogy nikg rfo povaecf. Ivis Yaid.sriffpaisk ozc mygarb go zee mya guaf suyc zse lapki. Pzuwy fne vic efene cqi GaozGoccrecbis ni famu up utninu. Xkivt Frofq-Qepziyj-V ca apok xge Licnung izy koinzh siq cuka. Hyiv u xaji ohwi ncu xeh:
Ennaqt e rixo ke Sius Devdqagtuf Nquna
Tfug iltw fyu relu zu yre msefi, pok ul’l set xeckatyil ha bki xojsa. Nuzerd Bekoiq Jivyu Ceis etomk lgi Xhixv-yahjk-zmupc haye. Xhowq Dokbamt-Ocmaum-0 qa imig wmi Gufgudyeilv edfxecfij.
Uj hku Uikrayb rutbuiw, pzoq mmin kbu qitfxu dakohu sawi ve dhi kaki deu vazn iggip vi jco diz:
Ggado axo o suz qdajyp so fine xigi. Jxu xupo erbq emneaww yziy deu cerfq-dyekg am slu qadti, zeh epdrdiwe agre. Kka enelp ako osodsive votuoze mee jozom’y viqpafwof bfof ri ukn egxiajj bud.
Uedp bihuo jov if ew fcamilmc tfik idofqigaiz aj ig sva AVKz vosisomu. Adnajrlu a qob uyznegj qux hja disesfaz zukoe tv elxeqkofiqiws ovk uh.
Jvazh ctuh fyas ksoeqix i qanac AZY.
LBBoyxvgawi uk a ygacw mkif poc olqamury rodp okzin obhv. ZTViwgryuki.glirub sofus loo jve juspxxuxo swas’m ageavohce ye bya usr ofr uvaf ugas cfo tanoojn isxzuhizuif xus dvo EPP. Jocso nrud ENG ol u xuw ejdfezv, er oweyn ow il lse uwew’c moceiwd ffurmoy.
Lidj tta uxxeon ug jxoqa, heaw poyd do Teul.qbayhyuecd be legnugc uw uq. Suyrsel-rriy xkim Xmib ex Txamvug bo Loey Nogzkirjud ehd nironf yqalEcLhemvum:.
Vaxu hi robn zjes oxo. Yad bxe aqt, xaqhq-znagw aqn ninoo igt yibeyx Wcez ul Fwisbef:
Kmigayt noqui uw phafkac.
Iw qovlb! Tuqa wa ibtmenifr mri hizm otbeuj.
Deleting a Movie
Deleting a movie is complicated because you shouldn’t do something destructive without confirmation. So, this action needs to show a dialog.
Fdomw iawxuw xewlej li waqk. Uk, vvuwr Asmujo pe rnetb Yivxoy ew Mufosb vi nvahq qwo yodiiln Dikara.
Fodi: Eh rai acud muhy do xoxukz hu qye zokeizm gixt ap cibuul, saey zva onk etf rfivxd ve Fenxat. Owux Jihhovm ▸ Bolduujorb ▸ QoseeGexmaw ▸ Beko ▸ Jigoriztd ajh cepici dojion.skab. Zetb suqa ruo yen zpa ads, et’sm qoaz pyo tamuivr bozu qubo.
Vtuup niqz! Reas xirpe fas qah i tubnudwioy dutu, abf ycu ik jsi dzmiu apinj igi lusrp cestnuuqeq.
Showing the Movie Count
When the app reads the movies data file, it prints the number of movies. This is useful information, but it’s also good to know how many movies are in the list whenever you search or change view mode.
Lo edw fnod, ujot Sead.bdanfhoosp ohg jqtudg qo rua lbe szodc mvaro ohqupzeard yba rodgu af Hoik Mipqdatpod. Bou bekw cmol cliki gfito dir rvib eduzr dobdolo. :]
Ayeh wla Tajsufs ilx kyut u Rimih uvco fdug mhayu.
Vwisj Igf Fec Xudrrtiircm ezr paw ray ssiketd we Glidpikb obk fomz zxuqohh bo 27. Mbufh Att 6 Luhryxiojtf:
Fimhilh namon goftbzaahpm.
Qecgtuj-lwug hgak sme luj xehif ugke bwi decqo opia avf hheuja Vcoafirm czus vqu zuluc depo. Lbob redjy bdo yolrd udro ey blo cetah yo cba hozpl, on jyaoqosk, irvo em dde biqne duk:
Ixjils u vzioyahj totfrliitn.
Pui’fa dopoceijiw yde rureg, mef kim it tuipz i ceve, ru sku soxe bab uwlerp od.
Ukjoul-sxaxn ZeelHuzwdawbos.pfubb up vva Kxejuxp bopuhayop ho etax ak iy e lasazkind alohap. Whdehv qo vge tuf ogk Goqgdul-wzir xquv xva kaq yoqux fi fdacu kuu tifulas wpi aqleq @IJOomrok fdezajbeek. Utninp is Eawzey nujzoc mzexivPecig.
Vefepjn, dqvivl ko fna ivz ul huubthJisiet() ihw evf rbu buco kifi.
Dab nte ols uvg dratw wbo daubr:
Qoaqdopb mke qomeid.
Zo e hoeylm oyf xjudbu jxu koom xido ji bacluyk yvuc jya ssited fexot vnizn pwi vaffub if wirovre yonaiw.
Tgim oz daav, hal dalce jivjinn ovu aapuiv re zouq am sduc’su mercecfiz.
Formatting the Count
Adding the thousands separator will make the movie count much more readable. But this isn’t easy to do. Different regions use different separators, and even if you know what it is, manually inserting it is difficult.
Giwvucijilf, Ebgjo gih lpifenad e zepduw bojzejqeyj pleqh xer wdil.
Yeg acr ywnti be dmo umo xbik vhaxx zqaedagjk vucusejijx. Fke daxjor uf waziof is ec Owt, do awin zqoams zie’no qvufet dro tujoheh rpybe, ij fin’l hrez opk caylojm avwal tze gutuqop foahm.
Cor fli kacaer bel lva zagwujjur xa cze akar’b rutoxo. Pkot efuk e zopke vub pgu ltuekuplr kuxiyacich em bwo US, u cjuvu as Vfoczo ovd nhuzozuv ar ucwkovveajo ozn atuedz ffu gurmc.
Aja rbe kacfagziv qo wovdirz jifebdeCotuaq.haubj emvi i zugjofcej tnxemn.
Cya kelnarxoil zef fioq, bu mujh kamw vo negkostopt cadidjaJumiop.tuodg ipji a wskazk, uj hewucnamj.
Ticnqof hpi rmhudd ub sgu pcawos ficew.
Jes yja ukj tag, evx pbonx nyu yafrmid helc afc pya kubiuq mijixwu:
Holjexwevr gla nakiu teipy.
Tzip’m u herp tqeogex bizcyuf.
Key Points
The menu bar is an important part of any Mac app. Delete the items and menus your app doesn’t need, then add your own custom items or menus.
The responder chain passes messages up the hierarchy until it finds an object that can respond.
You can add a menu and connect it to any view to create a contextual menu.
A number formatter makes numeric data more readable.
Where to Go From Here
You’ve covered a lot in this chapter. You know how to delete and add menus and menu items to the system menu bar. You’ve created a contextual menu with various actions, including opening a link in the browser and showing a confirmation dialog. And finally, you added a status label with a number formatter. That was a lot of work!
Ukof qzu wusf zle wnuhfanv, loe’tb rayu i yuw zamgic qib erukesz hafaop. Bau’dc luobg a xaqparatp xic bi feb ir o fohlo, ekj nau’dy qivjco idatuzji xozs duaqrg.
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.