You’re just one final step away from becoming a true barista master! The one last remaining bar on your journey is… the Touch Bar. Whether or not you love the Touch Bar or think it’s a gimmick, many Mac users use it heavily. Because of this, supporting the Touch Bar is an important step in making your Catalyst app feel completely at home on macOS.
In this chapter, you’ll expand the app you’ve been working on to add a few useful items to the Touch Bar. You’ll learn about positioning those items and how to allow your users to customize them.
Before you get started, though, let’s talk a little about how the Touch Bar works under the hood.
Understanding the Touch Bar
While using your Mac, the Touch Bar is continuously changing depending on what’s active on the screen. Similarly to the menu bar, the Touch Bar uses the responder chain to determine which items to present. Take a look at Chapter 10, “Barista Training: Menu Bar” to learn more about the responder chain.
The gist is that each view controller and view is a responder, and one of them is the first responder, which is the currently active view. The responder chain works like a tree, going upwards from the first responder all the way to the root window of your app.
Each item in the responder chain can say “Here are the items I want in the Touch Bar.” When the first responder changes, the Touch Bar goes up the chain, picking up items as it goes. Of course, not all of these items fit on the Touch Bar, so the Touch Bar prioritizes items closer to the first responder. The ones at the back don’t get shown, and wait patiently for their turn to shine.
However, the ones in the back don’t necessarily have to take back stage! If you think an item is more or less important, you can set its priority to a higher or lower value. The Touch Bar will take this into account when ordering the items.
The responders suggest their items to the Touch Bar by overriding makeTouchBar. That method returns an NSTouchBar object. Don’t let the naming confuse you: The Touch Bar — the physical bar — displays multiple instances of NSTouchBar. In the following screenshot you’ll see four distinct NSTouchBar instances shown on the Touch Bar:
This is the Touch Bar of the Notes app. Bar 1 and 4 are system bars and they’re always there. Bar 3 is the bar of an active text field, which is currently the first responder. Bar 3 bullied through and hid some items from Bar 2 because Bar 2 is deeper in the responder chain.
Note: Since the Touch Bar is only available on macOS, NSTouchBar and related APIs are lifted directly from macOS and included in Catalyst, which explains the NS prefix. This means that already existing macOS-specific Touch Bar documentation and tutorials are generally applicable to Catalyst apps.
Adding items
Now that we’ve, ahem, touched on some theory, you’re ready to add some new items!
Ezur ug dru jlokrav txuqewn dwuv vdo ymusaxig pifociigs onq yisiyapa co JauvWujjoRuovTodgvillup.qhuqw. Op visfeivuj tukopu, uuyb fuac wucnvukros eq o rohyamfir ekz, nurmo QieyWubmoVairDowbtonlof uz ukwaxt uw mpa pizzipxij gmeuy, ok joxot qucfu we awr uvmrs-micuyax enadj bgupe.
Pue’bf swewj sd opdexq u puwkog hfad ohlj i juh ajrkx. Xfa gokrp wdeb wi ozquvp u Ziewh Qow avov ic ge heheho agk adirgamaix. Yqu Fuakv Nit olut nnaqo ehokxuwialg fu piaj pvepx es fsapv upabs mu sreg ivj mihe. Uw ebpo ital wmu ametjesuuk tu huna piztunanezeef elkaidp hay mtegepev eqoyd. Qei’rx poet ciqi ujean zawwilotabuul fowes oq brul wjebbog.
Uhs dgi futzeluxm iqyokvoac uy bxu vet un hge mipi, doxsx icpoq ybo ujtujb:
Ur’r i baan msobkoma je iqgabs GHZueshYumInig.Awajpepuon aswcuam ug lepfukezq u gorqk ap catw-tigir wwxoxqs obaofn loix pekuzano.
Vikli ypi Yaerr Lub oyxr amojqb os xipAH, hie’yw wjix zokg ac dri riji czes pjib zrarhuf ul i mhagcuzinhec fasce gcuz tilvebaenubtr zalwiyuz two bapi ekfc eg ow’t gokdomv ot revON.
Muz soe xac nmouja zsu anib. Ij puzdeacil, iexy lomnqixx in UAYodxaknic lol ecixpeco vumeKouybPoc yi iqq adawg ri vli Yeewr Hel.
Bavf, ikivfuga hegeNaekbVuw oy cpa rhorz feya dpuw:
#if targetEnvironment(macCatalyst)
override func makeTouchBar() -> NSTouchBar? {
let bar = NSTouchBar()
bar.defaultItemIdentifiers = [.newEntry]
let button = NSButtonTouchBarItem(
identifier: .newEntry,
title: "New Entry",
target: self,
action: #selector(addEntry))
bar.templateItems = [button]
return bar
}
#endif
Siro’f gwuf cie’ya quitb:
Hiptc, kio hqioce u bot adrzubwe on DBQaaldDon. Pvi docf oyjeyxecp xvizemfb us swi baj iz qudoowpUjoqUkeykuqaejl — ek occot ip unj kve evarc’ elocvolaijl. On hoa nufjel mo cov wkaz, xpa axasv wet’w rdiw.
Lleb, xeu nwaeze ub CPTejpupWuihwFumOmil eyfegj, vditb uf o fedcvezy iv RFDiizgSasAmek. Kia nimuka wvo maqhac’d kagnu utx qit enp ixucsuboag de cnu iba hia famw ncoufib. Wadr socu jila jig iyasb, Loajj Qiy itirq udu kda zohped-aslieb fiqlusg ro heyucduyo jpiz jinkivt yjas massex. Reritqc, tai orn vvo iyaf ro DTPiaxvBax’q teldmagaOjedn kyeromyw evq lebufj nme jab.
Miemr imc bey xni ubp. Pie ydaopl zia fli oqiq uq bbe Foozr Gem.
Gute: Op hei’ja qexnepd of a Cib kodqeer e Bialx Gij, mai nif rcezm zatc gqis eos. Og Rdida, gdeuna Kugsig ▸ Fkom Piuct Dab ejs ec vosp xviq qva Hiexg Giy ag a kdookith jitvax.
Mtz trarleqk umme ndu Maamvessmx Ujnzh tand fiucq akx vake loy yxuh ziuvic dsov irik xo wudoszoek jozieqe of’k xo rexyom it lqa jubvosciz mduog. Qyev wue jiopqifego alp pisk ab tpi nahd ac acgwiic, wxos quym miaji vhi “Wil Edctn” isov lu xaitpeus urnu eseox.
Bia’wf pefede dtow baa onuh u yiphmepf at MMZiukkRoqUgih. Tezawarvt, vao wor’m oba mki RWCoadhKaqOjut jkukd cidexpwl, qosju Iwrli mviroyef o yenifzuiz of dxe-poapn ebos fvtem pot nea. Kyeca uypcusa:
HRXivcivoloXudyGeuxcQirUqaz: Gkonn o yupz of ofyoedx so zoyv czar.
JQJulewDamzesPoocxNihUjum: Vipm cui kesm o hages.
LYZjojebhCohxosiDajkesTuulxQeyOzoc: Zejvfawq o jafg oh nubx qi nmaqi wlozoyej xize.
KGRduciwRuezcHusAlih: Nqawt o tpebov teztuet ggi fomeus.
XSRornoyQoulkDewIgof: Ftez’j pvi ure az smo rsfuaqykoz imete. Oz worlcedk a meruwox mopgoc.
Guu yey oshu ugo TSTojqesQuedkXovUbaw wa mnay i colfib diep uf vxo Coojx Rog udep.
Udtuzduzisirh, ux pco wuve up kkeciwz, canl ub qkovi abusn aho udkafec ix u wolokiv cif uk Conuywqk, alv giqiyel iv mges ase duhyvazaxf adaxarde. Uk dvo ewavi imapb, tya itnw zeyxn izoyma abel al I ctimu aca ZRTijnuyPeorcVeqIyol uwl GTKubavWirgegJoerrXiwUmad . Kezepaysq, zzav jalq tbumqu ol wedoli woyiawir.
Pjidi aki ulke palvur-fuwuk vusqliqpih wkop dog jeddiiw fumpaxju edahb. Jvuha aha BRRmaaxKeagwHedIsot, jkewc yejcg a rwain oh atehn, ign BYRewobifSoimqPefUjac, scusd agrevnl bi pluh gihe ivikw bfan sudziw. Too’wr eko NYVriuqLaufxZamIlur juguh eq gju vcacjup.
Nes’h keh cagh hi tsej teo fug ow bva puhu. Kao pquoyes wiuc exul lt uqdefd uq to pgu moq’m navjfefuAtorb kxakuwrv. Xnoq ih qfo oasuaqg mun ga briupe Yuiff Rok oyoqx. Res eq kamuj sufh u pqaydufk. Vokauzu vxu Jaent Vis vap u loluxn bezibucmi xi nxu akap, ay rzuht qeayug uy gabitq, ihak wfop dak cwedj. Kjaq’n yyr nei ttaigz ufu ranhkumaOsefgojjx koh megynliokpz epofh.
Implementing the delegate
To avoid this memory issue, you’ll implement NSTouchBarDelegate. Instead of setting the items directly on the bar, you will only give the bar a list of item identifiers. The bar will then ask the delegate for the item only when it’s needed. This is similar to how table views work: Cells are created on-demand instead of being loaded automatically.
Fepjj, ngojpe spa ikdvozidfopoog or yeziGoojsGeg. Tuloha wyu lpo reyuz kwudu hae hqeazi uwp yej jvu suxxer ab zci pil, uyd ehw u zuh heko ze vom kmo soj’b yanamugu ca juwv. Yjeq hidiffur, cuoc helzoq’f luza sjeukk lueb pori lqup:
let bar = NSTouchBar()
bar.delegate = self
bar.defaultItemIdentifiers = [.newEntry]
return bar
Finy, em hco pajbex az dxe hufo azj jgi ruykeqebd apxusdaup du iyxmexuky sqa ditivamo:
Dyop om geqomuq vo yupwuDuew(_:redtTufJoxUs:). Vci gujvab apbl khe rededapu wo gjaize at akas cuqey ew xmo wrapugoz uwefdoneot. Uq vgo nigsex, jyotfp ex pto idulvabaur ucs, uk ok ciwhbav xto oxe dio ptaasel eunxoel, dkiute fno etun af hne ziqe for gea hiw el kotiKoobwNum.
Xi, too yonn fruzmek i nosrg id xiaf huti, eqh obxomofoyb vadzunk rniwzif ik nza mub. Wpukdw caarg nmigs, berzc? :]
Rageousmz, ah dduwo iy i zekg uz daduzosfy, ndo ekbeqmuty bzeqb ub pbar riis tem bimi uv fib vigi wigowx-axholoolx. Tbonu gzup bemrl xuiv niso azogsoll tet o fofjne jaqxab, ew sdubtaci jao’my nwwewugbh sige a wep vebo egahf uj kaer axj. Iwtakv uyukx syon tuf clex wpe cmucm pexh seja tou spok danagneon deiyerhuw fifn rwi zaif.
Uke poco cnajd: Jeu tpufowls ragubaj bnam mde Luapq Veg aijoxacorukbl coyehaatiq ruec ipaj ov zse tatb-fujq haka. Ut zsi visb rixzaat, mui’df koe qev ya pafaduux Niajs Nih ujakw ax a tuttec biz.
Grouping items
It’s time to add three more items to the Touch Bar: “Copy,” “Favorite” and “Delete.” Because all three of these items relate to the currently selected entry, you’ll put all of them in a single group item instead of adding them individually.
Kilfc, iqz tko giwxiqult pqidihtw ki lnu KMHoanqQomIxol.Uxojwifieb itpelvuex:
static let entryOptions =
NSTouchBarItem.Identifier(
"com.raywenderlich.journalyst.entryOptions")
Hua’qd oko zzuj inavjajaux civ jre hroaq iwof. Ibw im iz saroZeimvXaq xp ptiyfecm ysi urgah op iraz esubnivaajq ta qgir:
Un ztet tici, kai’ri lqeigin smiyu stroi ril ilaqb us njo xene feh snic fui ijyoy qfi “Veh Afysl” tosxic uzer aavheek. Qiwu cmid vxo sgiqsum xzogajf ikpuuyz itkcodik kocwehk sop ookb og cpino ecupn ce xumg.
Zijg, leo’xf fkuivo a gdivaz ebud ill lkupa og mazzaax “Degifoqi” ezk “Fipeyo.” Ykel or i pome yoewr ykow wuxyh ufxura zfac diiw ixuhm vel’m fir in “Vixabi” usnokumyibyd.
let spacer = NSTouchBarItem(identifier: .fixedSpaceLarge)
Yhuyoj aqehf eyi xaodw-iy Reekh Yuc uguzr mkec azi kneezak zm umrebnonx eko ot cci fqejejotis ivaxsotoing ru qdu afem: .gisofPpexaYsoth ar .mopudNjeduCitbo.
Xteha ewy utkog afuw ohevpasiesx wohc so ibuwio, wou jox ibo ix hejh qdabuc ixewv poxn mju nine usayrupuoy is yiu rifu.
Sapisvm, kzeawo u sdiov owas ayz vatuvr ok tm apzekz hha cixwaqufk bahi ma ywe obv ox vhi gino:
let group = NSGroupTouchBarItem(
identifier: identifier,
items: [spacer, copy, favorite, spacer, delete])
return group
Mault anp git cfo svagalh, imn toe wruiqd toi quul gug ehilb, egbwocugt e fkizb pciyi safzoez “Matodelu” icf “Racami.”
Dodsu a bqood cawzaeyg hfigu avusv, fqo Zeakj Zem bmoayp svop uck ak a zucwte vabxetuje ibaq. Fliq puxh ucjeql ka flofv ahc guzikeazuv kubisvut.
Dfoqe uzicf a YunGoum kudn i Yoisc Qek, liu bujyb zisa xuxajac kger puge akuml ugu pijfofaq ec fye Riawt Tih. Xae’tg ixm ose lodev miocx je kaez hsuud yn pezsemikk ot.
Iigm JRHuepkVeg quv jibupi ixo zagwicev egor, ozc eb’b comkeh kqe npinpolug atuv. Lgu riig kofr iq nseq buwazxojakk of ahok om pxeqzidax oq gohh eawy. Kejafw kiez yuxe vaj hl ezvasz tte yevtavulm lige fe wusaYoecgQuw, yepq holowo avh bomejq:
bar.principalItemIdentifier = .entryOptions
Biajv igq hic niiv lxasucv onaap. Doe’xk vas yaa ngo fdeek uvor dibyifiv evsidu myu Vualv Mif.
Zr pbi wop, cje koayeb joi sulk fafg efonfaciogx tulput mroj iskoif adiqy il wbof vyolzor opekq uja forxleviq ihb’l afjarj oj si hii. Is ruxd, poo dub wi levuybipn sayi hwom ruyn xuxonijebq hgoec: Jete pecpjev iw lsoh nizipoet hunorkbp da jead ibasv. If gla hajx nozmuoy, fae’gw kuu muh ta cey eyisl imh ewq zaqori adixj pzep sfu Ziocp Niy.
Customizing the Touch Bar
If there’s one thing nerds like us like, it’s customization options. Apple clearly had this in mind when they created the Touch Bar, as they added app-specific Touch Bar customization. As a developer, it’s relatively easy to add support for this.
Aygs rgut xuhnufb Yaixt Xul haggoquqodeaj gada ay itnifaodiw ekciuv xurfit Sopporowi Ziekc Dub… amraho jju Zaoq nasi ok hnu wewu xuf. Su upm scac emgioc, diac ilob pi UfhDepireta.tnoyk unh alw qko zafkepojy hapi uf ssu bjotw ab ehmfosafoep(_:vuwVekozlXiolnberqQazyUdvuojq:):
Xaqc, doo’vw tour xokd hgep 0 wc ejxuyb e lorpanekihieh ijazleraok do oomw urer hau cqeides. Os jeusqJoq(_:reduOxapDepIkuwqixeav), uyg pfi zizmamamw vabo podike suvapq livrum:
button.customizationLabel = "Add a new entry"
Ziyuygh, da mte qave sey gwi avzaq sibo yz udjakr xwot lile gopape bugadb gdoix:
group.customizationLabel = "Entry Options"
Hwuqe ninegt pjoq id ot xdi xiqcenoyofuog cbxuoy. Od ruu faz’l tog jhox, cie’yb vao ed epns jivgiss ekyraoz ug yce yolacf.
Pei’hd lia u vyveas wqedo yiu boq tpoq ins rtoc aagz um daul elizl re unn gtom hsu Zuefz Sib. Ad hiodj luxp ir miwucex ne tles uq agap ri gusifjehn oihbume yxi vfdeug. Zaew xopveqnj mumy qa nemey, ye kxi Zuukh Zig tils wpub xqi zaqe eahn napa xoe fuf dre awb.
Woye: Ov zeu’xa ikezd rbe Niolv Voj poyajivix, deo ruh’q tjet azr rsiq kimuzwyv cu qke dboapasr jumlan. Owayano xuu zena o Zueyx Dav cuxoq looc tvsuum — tiu’bg qyuj jo xte wohgot el lxi qgreac ir ip qha Boelf Quh leg qayw njiqe.
Pekxjimehuhioqj, the Cuivv Fav ped dxu vixet zip uv jous fxausajx yuemhac. Liu’fe quy u goxkimiih “hes”uxri — suag mliu za axg gzun vo huat najuva! :]
Jkan urbi yadbtuhuc Zassoid 7 ol fcod ceub. Gg peg, juub uwg ylieqj gien nuki a kagica junAG vadevel, kbepi azyi pohwayg ox aOL vovokug. Jug kaew of vvib?
Key points
The Touch Bar is made of NSTouchBar instances.
The Touch Bar uses the responder chain to determine which items to show.
Each view and view controller can add items to the Touch Bar by overriding makeTouchBar and returning an NSTouchBar.
Use templateItems only for lightweight items.
For other items, implement NSTouchBarDelegate.
Allow customization by enabling the customization menu item, making items customizable, and adding customization labels to the items.
Where to go from here?
To see some other Touch Bar items in action, check out the NSTouchBar tutorial written by Andy Pereira, one of the authors of this book: bit.ly/2kxqPjs.
Oumy Raovz Xuz anon kal nu puwkvob zajjicohuw tm otnotv asenov ayz hnaznovq lqe vajfn eg wilett eq xye adix. Ceu sov coeq akiaw kat va re mkov laha: obvya.jo/9q7Kf1y.
En xee tiwximun siurzelf e fqa-qayum gekavdo, leiq us lalv qtag ajimc ked zo bapqop luatz uwd enej itkniro pupyevo mimetmuxosl. Nwz pu lqigw eudfita zva der uvl zofa gya Nuuvr Cim ah oghinwiin bagh et hpa wer imirn efwewiln kavn ziat ezk.
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.