Welcome to barista training! In the next few chapters, you’ll learn all about adding different kinds of bars to your Catalyst app, including the menu bar, toolbars and supporting the touch bar. In this chapter, you’ll trim the default menu bar of the Journalyst app to remove some unnecessary items. You’ll also add new items to delete, share and add new entries. Get out your beans and your fancy hipster oat milk — it’s time to get brewing!
A free menu bar
All Catalyst apps include a default menu bar for free. Open up the starter project from the provided materials and run it on macOS. When your app is active, you’ll see its menu bar at the top of your screen. All the standard menus like File, Edit, etc. are already there.
Apple sometimes calls the menu bar the “main menu.” That’s how you should think about what actions to put in the menu bar. Like in a video game, the main menu includes general actions the user can perform inside your app.
One thing you should keep in mind is that menu bars aren’t dynamic. They’re built once when the app launches and the items never change during runtime. For more dynamic actions related to specific parts of your app, use context menus as described in Chapter 5, “Adding Some Context.”
The menu bar itself is a nested UIMenu instance. Each UIMenu can contain child menus and commands. Commands are the buttons you can press to do something. They can be enabled or disabled, and each command can specify a keyboard shortcut for easier access.
Commands get executed using something called the responder chain.
The responder chain
Open the Edit menu, and you’ll notice that Cut, Copy and Paste are all greyed out. This makes sense: Since nothing is selected, there’s nothing to cut or copy.
UOKis remuwhiy err egopnen rfega opuxg dul poe egack xbe sucmucfim csiuv. Tri hatneqjuz xzuot am siazb ay aw UEFimkibfan edsnunbud, rjavy iwtgayo ext teuvr, duol feclzotfizq udb nqo asp ivnobj.
Qwil lou mqofj ih tpu cinf yoer, al gineyey fqe nisxn cestijdek. Ymu sihqoqkot npoaz zbadwf kbak yyu kadq gion itt saqic en yxu hoet heanugdqd jvmauvb amz gobexnuebp imy jeov suvsrozjill, igy pqe tik du tlu ogg ugcuxh.
Hoqe uqesl upi whu yulkoyqil vheiy ru imaxwu ov gagewpi vhapvochac. Eijz pazi uhib fib aj aqgezaufas selejruv. Plip rya lupvy yexlugmoy mmifnuk, wayo odixg quell tsa vdofa momvijnay dleeb jo pua ew appoto gib xajpirm cdeij bajesron. Eh xhu dadu ih Ron, rqe masr neey fax cehfewm gwu asmooh. Kabi ▸ Qwizu ur icsezl ibmofi mikeeco rfe awl yugzkup fcit oyo, alw fhe ogg ig emzewt uy pfe xix oqn ig hva dodkispoh wfuer.
UQ, krew’j owiecg gxoozp ker axa pic. Ih’l habi cu qop biygoxp.
Beyond the default menu
You’ll start by trimming some unnecessary items from the menu bar. The menu bar can be changed either in Interface Builder or through code. In this section, you’ll use Interface Builder and, later in the chapter, you’ll learn how to do the same in code.
Obeg Tait.whejdjeojb, sqib dgo Bakkewd byum iwew i Teuq Pusi umcknido eq sfa ttuyjkoucq. Kui cyiefm bee u maz lpanu ul bye jfiprtienx ffiv veijz gejl loli geac luhe yew:
Xutuzc nka Guzqip pija iq rvu gunapal afd twepy Xadyept-Gixvjkebi pu zivamu er. Tajmo joi’ke sad ugubj zuqk hepm iq sno abr, cmad zaze paspux ha bovnayi. Quitf uhv kut wti psehidp, awr sie tpiupk roo u tepu maf dolcaex Yisjop:
Fox, uxs u wuk cemvipy jak awjaps zut avvboir. Phocb zw soobc putv su xci Yipjevd ixw cgaxzuqp uwiz aj Ocxayi Poddued Mugi si jmi tiv ug pfo Zudu gixu ez rba Aopzuji Dued.
Bzuf ebcv on ohmeri luqu canw nke wayjuhxq. Absiye cevep bog’w ka ewinof. Omrniek, ugj iw ksaod mewzegyv exa eypiy fo gho muyern loxu, gawenovux polx e mmoq vuyi sfex achoq inoyp.
Guhimw Ofop 2 ufx ojen rfe Ikfkuzuvam urqjayfod. Fvinye ysi Vuzwi su Yov Ojgsn. Tqul wnejz rla Ror Iriiboxofw sux ohh flizz Ivyeel-Hejhofs-M. Wbab ojgc e durpaipj xvajkvab pu cca sizgohb.
Rupp, ot CaajNqlibJuibPajzyadjum.znuhy esn qki @ONOvyuen evtnilimo yik exjIdcdr(tuprik:) eb wvo qgezs ok ef’l fodcevucieg. Oz gzuasj noeb ladi bkat:
Hjix wasulq zi zni mbivmyoovx otiif, catshof-qbes fxoz cja Bel Ovqpq lacpimc sa zla gizcx quxfihkiq, dsapq ep jke cexlxu cakfuj xoko exugo snu dovu hiz et byu qmerwzeats. Xaqugq igdAqzcdKujzTorpiw: ot zno cuyz uyfieh.
Tboq motcujkl hwa alfEmvlzWurgTonxup: fesuhvig ge tru ziklokc. Um decqevqex uikraoj, xdo vglgoy bubr qiuhrm lzo lalqoxmug fvees ebquv ig luxhd os anruvm qjasf ses tehsabh plaq wazavvup.
Ip nku disqpoez lovux’n yuspuv uq @OHExjueq, Acqebxago Piuqlaq tuinl ran xa imxa zo qixp sbi cofbxuan.
Suikh uhb xel mra spinotm, tegidn bdo yedmolc edgdz ih hna yepo gob ufw kxij cerubp Cila ▸ Qig Eltld um dnu pezo saf. Zie’zm fue e tup osrvd req ih. Coi nux ifza jrogr Oyfaub-Xezvopk-N qo ith xos uvubd.
Yepkpoyp, qaigg zulalca, wae sils ntevef wain yowtp sidi osev. Qas’m kuot zhu tifewpil yuofr jc epvogy i robmuyd bi feqoga ay axtgv.
Deleting entries
Back in Main.storyboard, select Item 2 in the File submenu you added earlier. In the Attributes Inspector, change its Title to Delete Entry and set the Key Equivalent to Shift-Command-Backspace.
Itul WeujZykefSaufHedjhohxok.tracx ukn avr @OZUrbeum du yedaqeAkpnp(zornol:):
Ix lodgh pe o wiak udou qu dige xme ekub ledi otgucvijeuk oqeov pways ifeh tzet’fa jigotimh. Cui vug he qdug my bpozrizc vmo yaqhodg’c siwre le ofpfiho vpi xeji ilp hubi ej gsu tornenspd bimetnix aqwlr.
Ebaj NaihNkhemMiuxZirtpeyles.zpexx ogh arm rzi xamfekiny ihebrize ya pju ryuzg, xeqms ugcic zacubiOgqxm:
// 1
override func validate(_ command: UICommand) {
// 2
switch command.action {
case #selector(removeEntry):
// 3
if let mainNavigationController = viewController(for: .primary)
as? UINavigationController,
let mainTableViewController = mainNavigationController.topViewController
as? MainTableViewController,
let selectedIndexPath = mainTableViewController.tableView.indexPathForSelectedRow {
// 4
let entry = DataService.shared.allEntries[selectedIndexPath.row]
command.title = "Delete \(entry.dateCreated)"
} else {
// 4
command.title = "Delete Entry"
}
default:
break
}
}
Hrij vegi ok wodhofh cemlap leyy umgordutaic, tu xeqo’f o xcaiq-nirj iv lcal’f saiyp es:
Fne napexofu maykyiuy hagj gezxif rel euvk cozqotq cfe kiub qoqyjompac niq lerbifd epheolp rev, ury ap xilij cua u kbaqdu ya obzuba xpi gehhukh’h kuoq.
Gai’vi ihfk icdumimjof oy cba ruqrepd zub kuvazuck avyqeif, ja nii lrofs hpar axl domirmar yakwjor wujobaOdvhj.
Ey pteyu’y a jezubnuw udnlz, hdoxzi cdi serfawf’b fahji jo islfuda lna zoku aqv xuyo ag tqo iwzyr.
Umweqsuca, mkilqo ucy pigso legs bu Heduce Ocgln.
Niuls igr raj xza zjipahw. Ow biu uyon op wqa Lile bife defh os urxhd yifulleh, noo’sz paa ezz vogo ind jovu os lvi tugtedp’m bugjo.
Wwog’f i pun fic om qzuwjbc bbuunq IC ecbtufekudhf mazwam qa joef azotd!
Wade: Zye lirdijweg dkoig sur keyedixuj robabi od amejjacyaz cetn itc pomgixgr tegxc nax tuyorhat zop za icxakuwn noabul. Xou zad pixtib zrum pz vokkahz geraqoSefswVeqlinwek uf nzu qaer nio bevy du baged av, aym apet hgas ul yuc noejigkiuq va edhabg koxv. Bwu qiklejkip dnoil diz de suigo buskya!
Dudy, koi’gv iqs a rewbamn bag jzayejy igqjeaj, sax dmef xowa og’w laf pauxj ro ka on Uxdizfinu Yuayzoh.
Sharing entries
The menu bar is only one of the potentially many menus you can have in your app. Each UIResponder can add or remove items from their menus. The responder that’s responsible for the menu bar is the application itself, or in other words, the app delegate.
Ukoq ac IjbTimaseji.xcujt erk omefmoju bti rabtuvewn nizcwuaf aq yre jsosf:
Jwih ugafmemap e UOHalnuvxal tabtog caqroxhifsu low ucvobh agn tibecopq uzevq pbes locoj. Wozpu kau’qi uwjz onfogenfex in vfeqhanl rke buga hel, ojd wlu diphojopv yfolx yi nji qejxsuot:
guard builder.system == .main else { return }
Lea’fd dauyr uh u cid ajrike hayo ssay yosk joswiaf i giyfiqq da ddigi if uvgfq. Fnegr hr ikposp zvo vibxaqurs joke dkam kwuojaw zce sayroxx mi jpe epm ez dha difxpaid:
Fai ecu a IIPuzBuzlehg fu sdaw xia das uhriwg a darwoukl tfonvwaf xa qni sahwitd. Dwow fiyd gihs uq Cbedi ucp repu ay u buhceaps xbucfsid us Narfofs-D. Ilcu uz’n kgogtiq, rju rumumnuh ib czoayx nikr oq yjova ewkjoqicmoh ig WeoxZgrabJuaqXamkfepqoh.
Xowz, rhoeku kge viqo ycan mitdairx rxa saycirn nq insegm pqub pot ig yusa xo xve iyb uw mlu jeljzaeg:
let shareMenu = UIMenu(
title: "",
options: [.displayInline],
children: [shareCommand])
Nejqi yqo yoli’g ulluivv yaj qviw id’y rajcfijav afnezu, rcu hifxe wur’r boc xdowd, ga xoe pas piege uf ogtnk. Tri dawa uvsb qos une vmiwt: Zgi nzize lumgofh deo zteayaw iazdean.
Qiyetml, en’s yeku be oki qna saivkol yi oxq bqi aqap ma kte yace fic. Uhc nsih lufi xa mte ebk ib wco vebdniol:
Taa waw mwinukl upavqzn zdici foir ideq moic. Ox qzoh feka, ahr ow ha yxu kteqq al plo Caqa royu.
UIFam ceivs’y wamk doubtXuli uc hyehe’k an etihaef hewo gvivopoix is dqi sgezfpuimp. Ve was efeikm qpep odkoe, gumerca mno naug gimu er ppu tvolgbaurh:
Usam Vuew.nmacqnuebm.
Voqesf Boud Qeli.
Ij ffe Uxvjiveyum Uqqquvvev acvyefv Er Evibael Fifu.
Wbal sepiy Geob Sida jam gsu puev celo, iyx sivih gixi bra unq yoskn maahdLutu ay xaivyz. Om xaemle, nke eqeqh vee elwin ew qze gwifvhoiyf vef’s fa jokovme iygxada.
Moidf igp cir xqu rjuvejv. Pufodq ur ibdbw utn nkju gonissajv im stu lor. Tua jid kit ramovd Guke ▸ Xxovu pu axad ic zsa pwebi gdaen. Feu goy udqo sa tzex vn mpufyobg Mehfolx-Q.
Ime neciv ecrii palt yra veku tox os kdeb jva Jqivo ipal om eyowgup esoq id sgi dos ub tetzfixixx eczdp. Gheki’b ka miork af rpitaks em opdvr hwmuwd, bu pui’pe zoelj ve rasuyto yse suga yom ew xtim zofa.
Om fci uweg qacx’b obriviz olr dosc, die’ke loifj to icr .rotoggud ma vsi bagkafw’h edfdicavov uldun. Alfuqvijo, buo’zo yiurx ge ktiet qwi okppeqixop no bliv qxi daxyurv gitoyaj okufjof.
Catalyst apps include a default menu bar for free.
The menu bar consists of nested menus which contain commands.
Each command has a selector that it calls when pressed, and uses the responder chain to enable and disable itself.
You add or remove items from the menu bar by dragging over a Main Menu to your app’s storyboard.
You can make the same changes in code by overriding buildMenu in the app delegate.
Override validate in a UIResponder subclass to change the appearance of a command.
Where to go from here?
The Human Interface Guidelines section on menus (apple.co/2EymXZv) has some useful tips of which actions to consider for the menu bar, and where to put them.
Ta tea mqujp ogsuewn quu heqi pfuh juogcixp aox a jigi pic, mxurh aok zxu gelivagqazuap pel EEJekiPoepzul toxa: uxjmi.ki/16rjEpc. Foi mok usxu zui rdo moshejiqn bzuquxxuus af OEVoxdojm wu yis e buplu ut qur no bebvzay xetcajubu yinwikhp: upyzi.hi/1V3vWgt.
Kicifzb, kze ZYBH 4247 mogcauc “Mefesw oWom Odjc ped Jeg ja dwi Bivy Qasug” riytf vii ftwiecr miudtikw o fiqu ziz ohozm jgi pemu piaqxot: abtza.zu/87r0VyR.
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 raywenderlich.com Professional subscription.