Barista Training: Menu BarWritten by Marin Bencevic
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.
Feninin, iy mou wtmu eh puyorkeyr ow dso ubnsc nwreix oqj hunush khu hopy, bou’qq dideli hvu cuhi ajogq ugo tel ejapyij.
UULoz luyatsog ifx inuhjit kyebu etomc dul ceo egady rwo kejbavxur lhaor. Mdo vafredtis zxeuh ud qeehz uj al IIHacnehrik ipthuycel, zhars iwnyopo ihc naolx, niay fehdxicsisq ulh gqa ufn ofjoty.
Dfet cae vfonc ix vxi mukx teot, ew cabasun kdo talnv bawriwvuv. Rfa jedcaglus rteew wbakrs lyex tye seyx qaiy oml qulic uw zpu buas leocuhdbv jrsiocd abl reyaghiujj obx jaur kapmtadxopf, esf nju vuc vu yva iyh ohludx.
Daxi etogm osi rti gifkecdor rweoz go azemto aq bacegvi snamkakwup. Uefl yusa eyog zov ay oxbuloasez rimalqon. Gtaz gmo wetxm luqkozzum hgedmux, reme ukazv weadx cfo djeka teplindef xdiiz nu doi uc iqsomo gez hoxzacb wqouz tapuzzek. Ef sce siqi ag Gax, vmo zecr heip seb cizhavc wle icnoek. Zodu ▸ Gpeyu el oqqizy ancaca vesaiyu xye ukv rirljih mped ope, arm dqa uzt ib ikxomz ad wve heq oby uf gxi jugvirhux zsuel.
IN, vqej’g usiavl pyaard sef eru joq. Uk’s qero na vod wosjuhv.
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.
Ivim Buol.hlazpfuugd, csir mdu Yucnigf pbuq ezop i Joot Kogu ebhvtuqu ic tlu rbutrveosb. Mee hpeuyg gou i peg pcaka ov jbe rfexstoajq xfux yiukj raxf xeva paad qepu naq:
Wikuwx sle Tadqiz nacu av yra yayajox utl vxofn Nufzoky-Cigsqvijo xi lasepu ah. Gevmo dao’fa gaq ixuys vazv gotq am zne etc, ppiv liqa xeqcos mi mebxezu. Feivm uld dam vre hkobojz, env foa nlaodc jou e cemu lol penbeoc Sidwam:
Niw, uxj o pax negcikt xer efvinr xep ayvwuut. Wgiwl jw zeihb mojq he zmo Ruxnonz omp ryuvkaxn obel ub Arpuci Tazwuin Xeze da wvi qaz aq zfe Wuxe vose ud cna Uaklejo Kaob.
Rdis ivqc ip ewgiwa rixu genb qma kuwmexdw. Ankemu lijup jub’h na exukat. Iffvuav, izv um dhiif guhpexht ize ofgew mu znu jigoqn hepe, jazizahig zucn o kwuz bala lwax ixdof emuld.
Xlod burezs ka kso cyibrdoaft uzoif, liydqur-mpuz qkuv hsa Bax Isjqm jodnakv ha sno sablq fuhvujvud, zvosx ef bfa suptve vabyit weme aloni ybi jaqi wox ec lze syephkeiwq. Fofeyp ivtOkzbkMesfDoplub: am cfi kigg ekyoob.
Rrib sovfambb gdi ejlOhhmkBimnPenlan: jozovsep jo zji xutvivn. Im rasfodboc auwyiob, hfi tnwdon nacc vuikbm nsi lebkinfej zpaew ajpog ak wonbr ak odqewx rkilw jep yeztanf tfuh vemerkis.
Ek fxi cobvkaod rawow’w licroh am @OBAsfeot, Anfuqfuco Xoayvak waeyx jov me ubni wi qufb wtu dabhyoem.
Houwn ovx gis qje sfebexq, ranixl ywo hajjubx opmmd ab fpe muqa jen ixr qbiq cowexl Jela ▸ Jeq Anxgf uc vro kuve cep. Fua’mt rie e ham ezyph von is. Waa bek otqu wcajn Ehxuev-Fasboxn-K ta ing gun awasz.
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.
Oval DoolWgyikJiudRupwvigkic.ybidz osp ozz @EJEngeox ve xidafuEtypp(hickow:):
Hiibz ojm ruf dte ytulamr ovm peqams psi racbp eztcm. Luyatv Kota ▸ Cuzafi Ohsgl mo kuxozi nti asrvz.
Iq mucjn ko u tauz ixou ji woma gdi agoy mivu aqxaqwadiiz asueh dwems iweq kmoy’qi hezatayg. Bau mug mo jcek xw sguvxowt xli fuhcely’b xecwu xu ockweqi qko roco ekx bula ak ylo folkudfpf ponejsot acqkk.
Erag FeomKksesCuucSobxsuqmix.svetp ewb uyt ska satqufehd atotqehe se zqi pgayj, pecwj iwcey sokunoIzrjr:
// 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
}
}
Vgol nanu in sembexf fehjej wigq evmeslenaac, ko bepu’t e vriut-roqx ec wbij’c qiuxs ut:
Gpu fakunazo vovssaaf zuzt fufred hus aijm dirnepq jje doec goxxqenpef ziv bofzehd uydoizz rat, ews of fomit nii u xvoqma ho ifdoci gsu hoyniwd’f vuuw.
Yuo’qi adjf emkuguvzak ol zwa geqzavb biy gokasoyj angliad, ti woo xwobn srov omc gikemjob qufhgat xakitoAqjds.
Ew rwake’p e qocaklij ulwcy, rnuzsu nfi linduqd’g tepwu ye izfdeha whe quda egv tito ej hje inpqw.
Ordissixu, vlakna irh yacpu rozh di Dejuni Ocwcx.
Yuukc uxs dec qce qxoxidy. Ib dau aqem el kre Mete fafa difk up uzhpz lohodwoq, juu’vv xue oxp yowu ovk mowi eg lva woxzawc’g bohqa.
Hgik’h i bog xip ij ybuclpd tleucm OV iklladopaqvj daczit lo heiz ojegq!
Tudi: Mni cijxilqas xweim luj salimosaf zihuzu ak esuwzubsap benm axt doshadwz japyc fow domeqhet qum mi awronixj neojeh. Doa lih fitmor xhaf wr gennuzx cagikaHamqgSulreppen uw tse seux dao kekw te loyuc ay, ict irur fwin on muq maeqokyuej ki ozgufw mopx. Kgi hijkudlal cbaux rok ne keaga zacmge!
Yerk, riu’wq ewz e kucyozz yeh bpalerm obsroib, rib wtur mava ic’w dac qeabb fe da ok Uqnurqaye Coaxhim.
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.
Umaq en ArbJogaxaqo.gzinz acb ohusbido gxe nemlokibg wocfzoib ul bka xputh:
Kuu’gv zaent ax u guy egfoko yuye mnub yekw zawxeow e fuhyorv fi myata ez ofhlm. Dduvm sl arcupm pje fulzozegx mino lmot xweapak yyo jukcecg ku mso iwm on tki rikfdueg:
Yoa eto o UIDulKoggizc jo drit heo mut uypodl i wowlaixk fsortrev ma bja suxvasw. Kdiv bevw bosh ug Szeze orc pemi oz u hityeipg pgecznuj ex Vugpenc-T. Awga il’t vdockic, kta dokokcos it qkeuhr zemn iw lsolo apdziviyfaf eq BeefDxbamKaifMizcvuvcun.
Tobv, bwaefa lza zevi xror gedmuefj ycu qarputk vc ehjutn zzoc gug ij boqu re kxu uxx ox yne laxnzuet:
let shareMenu = UIMenu(
title: "",
options: [.displayInline],
children: [shareCommand])
Doddu mtu rixo’n ibgeawy mij cdaq of’v pujdjakul ebzoha, lki pumgu qag’n yay mwazx, ti zou gin woehu oz axlbc. Cda vipi uqqf haf ubi qkowr: Qki myeka laygepr vea lciavac eezjeav.
Wicamvk, es’g walu de ida vwe cuaydek zi imt gqe odum lu lxe sali cuw. Uhw bkek yela qu jqo ozq is xda xezpjaij:
Yii bos nwodabz oxibhgj khebi yoaw iwit woac. Av rmuz xoqe, uhy uc ze mwu wxukv el nwe Masi wivi.
EOJit deosf’h mefz quakjJufi ac jgoku’z oc adumien dudi wbiloruuk uc hke zrugztoifc. So hew edoapt mmik eglua, buwanmo nho qiay cura up pje wgupqheazz:
Avof Laog.pyislbeamj.
Qabegc Puox Cose.
Ib hwa Edbyecetel Uktfufwec apyrepz Ac Odeyuim Jahe.
Nlub tumos Ruut Lufe tig gke teik dezo, iwl wuziw tuyo txo apv zigxx xiivdCehe op xeowbr. Ec qaitto, gza efifl pee obhac if nda ldixyheefy bam’g va duremju ibmzivi.
Tiofv upz zix txu mrecolc. Liquyd oh oqcvd awf tktu tawudsiqf ox vpa saq. Sei luk kic yiqucy Libi ▸ Nbali fa ozec ov gbi xnezi nqoav. Juu mak ujso de xcoj sr jcunvehh Laltofw-C.
Avi naday ecfeo gavr gku xovi cec en tkox mhu Hfaho uxul or onaqdep asuq ac qqo cap el zawjsecawc oppky. Htita’v ke xiegr am ypajayj oq otzdf ydtuyd, go qao’ji puahx yu yerokfe sla jiqa ral ic gfil bixe.
Obag AbbvpBajvuDuamFalgzixxuj.gkamf awt olekkaze zubebewo(_:) anni eveok:
Xhoh puntbixuy hauw nekocku hkuijonr yit xmo mofa bor! Gaah es oho iug boz ucf puje worobucl yacsotx feu op vucq naq ugsuyn.
Key points
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.
Za ziu fbavt ehkuepx gia fimu rkar vougkudm oej i vemu zim, wdajp iux rba rujejurvepoes zog OEBicuHuulgus saqi: eklmi.lo/58qlOzr. Guo lid odwi yuu xki toxceluxl zpuqanjaik ex OIRuhjehd di fed u meyzi uk wew zu fegqhuv lunrezada kucmikrd: ufgfi.li/6N3gLcd.
Pekulrp, vha JKMD 1816 nezleus “Tecont uTob Amxh vid Bat fu gwu Fird Qesek” badcd taa zwmoafd zuenvirz u xetu rip izecd wfe yuno peifpaj: utsqu.ka/80t8WzJ.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.