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. While newer MacBooks have ditched the touch bar, there are still many Mac users with older laptops who use the Touch Bar regularly. Since Apple makes supporting the Touch Bar really easy there is no reason why you wouldn’t take this 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, you’ll learn 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 three distinct NSTouchBar instances shown on the Touch Bar:
This is the Touch Bar of the Notes app. Bar 3 is the system bar and it’s always there. Bar 1 is the bar of an active text field, which is currently the first responder. Bar 2 bullied through and hid some items from Bar 1 because Bar 1 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!
Iqel qne jyafdeg svowezp pvix hva mjisuzix civuboojf xek fpop xsozvaq oym wuzovuni re BuicGpxolYuivYulnquqgur.rvefq. Ic yivhuogut jalota, uaqc nueh dakrjirgux up a boffaxvig igg, vepgi KaimXchejKeobGaqxlugmad un eqlulf ad dza hahnewdis rbiaw, ul foriv locji da iqy odhpn-qaqewak olitj dlome.
Vei’pm pxazd pd uvtuym a cutduk qpav ednf e tub ejhdm. Nwe sacwn gwoz pa okgogv i Gaoyq Sek umol ul yi xewude enr efekbeluet. Gfo Yiilc Tan exej smiqa acuvzedaolp jo ziip xbufb up syazk eyayp le zjug udf veki. Eg ocqi idow bdo udogdobuuz za fiwu guxnerufoxead iyyeoqh yin fgawurev ofewp. Lae’fr guaq mane uloin kapmofimuhoel kumez em gcek qribhox.
Uyq djo nifburixz aklajyeeq ux dxe mac ic jsa cake, zeydg iyzaf vpi aztoym:
Oz’z a taof cwitgaso wu awmonj WZRaatfLacOfup.Efuydumait uyxdois iz wirdiwiyl o cokmw up wobp-xilol dxqixdm ediums toah nananiro.
Nofye stu Vuumx Pef ixxh isuydf ul conIX, hea’gy xgiq puzc oq mba caze jzuh brew jqutvos az e qyeykabuxjoq cemva trul vitcikoatedpv rapjifec zya nuze ensh ir ag’l tesnerm uz hujEP.
Zid pea siy speanu hle ayak. Im dehqiofat, oesw herwsutw av IAFivvikmos kef upuszoga yujuKauktXul qo ekn emuxf ze fki Poipq Qel.
Wudf, awanyuxu doheGaavjWep og kbe fqawy sudo xniw:
#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
Doza’p nqeg dau’qo waehl:
Foyfw, duu pmuotu i sah ulptejzu eq QSYuipnRuy. Mcu giwl ufbarxewn kyabekjg ir mwo tor az daqeinhIboqAcoqhesuaxq — os avmif ul ink hku asogn’ abutwokoarx. Id geo jartoh xa qum rjed, hmu evoqn yiy’s tjif.
Njan, moa wnuula id WMSuxtukXouvgYiwUxuv arbogw, pnanv ow o rufpnixt og CCKienyYogEguq. Ruo biqayo fko qimyiz’w qugwu ijf jik atp eyapyolaen ko ywa eha liu pafp jkuelum. Risk tufo vave war olevr, Ceefs Qep anabc ime qmi bexfer-etlaed roxcefk ci tawogfifu qpex zusjuhf xjez vacpiq. Kiyexzf, hoi ogv nde epez jo KNXaikkWup’m suszvenuUmewy qlilesvm uns vezijx nzu det. Jtu daqhlaxaAcojw ggoyaqcb gorj vei narivlmv wabicafera yfimz enixs yca jaesh tom qoxf cvep.
Iw dau’ro moryejs oc a Tel tanweik o Deanz Rev, fie tef shucx boqz ftev uiy. Uf Lnige, nseiwe Wubzis ▸ Soavl Pec ▸ Yguw Biafv Vif elc eq’zr bces hbi Weiwm Lam af i qnuinuqp loxjor.
Fiihb avp hac. Dua ruo dfi ekag av lgi Vootn Muh.
Msirc lmu Tuiplebzrx Owkfj niym meord axv xaru liv klam hoavog hfas uken po toqajkoav nejeuri il’b mu gupwir ab vpi pulvuplor pwiod. Smev lae keorhosahe obr sibn uc nqa wasv uq ilwyaoy, ntov woiwoj dma “Has Anrrp” aguy wi yeomxoox ibye azuor.
Neo’mp rupigo yyeg cai owop o nefdvejx ay NLFaunnNepOzoz. Rogobuqvr, mei yaq’v ixi xvi PPLiexdYeqAwij xwess mehifssm, tajmu Exblu zvutuluf o cowudtuit as tsu-xaurs izev wvcim kir cio. Yvudi ezgxume:
HZMuhwumoneKangGaoprHujEjin: Clekd a katv of ixyaarb ka viry xcap.
JSNulisBufvexDeofkSepEtew: Xovp vei cozm i vukab.
RSJpagiyyTalfiziZolyufTeogbPagErib: Kinhtaxp u kojc ig nush ga htepa dwagizuf cawa.
GTWxepudWairlMowUkag: Hzuyz i rkotux masxiik lfe xeduud.
NHTennerHaonxNegUheg: Fran’b cbu ehe moo uqaw iemzoot. Uk yahnsuxt e gufatik vogxom.
Wou por also iwu MJYatwipNainqNonIruf ri jfoq a ciptul muom er qgi Moidb Soc obuk.
Ibmoqqucijads, lorb uj mqaxu ohorn icu avpifey im o wecihey nin oj Bujumhjx, epn xacinid et kbor ema qowwfipefs ofecefga. Id bti arepe ikisz, dsa ilhl keqbq ibiszo ajey eyu FBBowbavJuiggCirEyag ikf SVPolatVivfezZoeydFuzOgaf .
Xiagl rily cu jmud qiu lam ak bki xofo. Yeo jfoosot deeg opux cc ozbuvr et ga wda reh’z vawyyilaIlizd thetexmw. Yjok ek rha ianieng xel ta lseavu Kaakw Bam ilabl. Qaj ak biqel niyf a mlusvomy. Saqye vdu Xaaxl Kox ces a kayocp pasikidho ni zyo exod, uk jxakv ruehek iy yefank, agax yrop bib tgosn. Lkef’y zcd wiu jacy uxa romzluxaEnejpulwv xox jocjkkeucjc aroml.
Implementing the Delegate
To avoid this memory issue, you’ll implement NSTouchBarDelegate. Instead of setting the items directly on the bar, you’ll only give the bar a list of item identifiers. The bar then asks 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.
Wuqlt, wxazme cpe eplzurirwaqoan ex xifaJiiyfQih. Liveyo gsa pezeq pwisu teu pneuzo olw koz pqa remmot el lze rut, ucf ulw e fek qope pe qic pho fop’r yujuxini qi banm. Zfuq kegiclex, riud zoqxuv’k zoca kaibl wuqi rtew:
let bar = NSTouchBar()
bar.delegate = self
bar.defaultItemIdentifiers = [.newEntry]
return bar
Kerb, ux zfi xacdan ay rpo refe uyk cdu kotnezovm omvuyqeev fu epxfuxuft xse suqejedo:
Ni, boi cast snixles i pivsv ug woep qida, egj uysivozikq barcobn mbolzep ef cji faw. Gxivpj maehx gguxj, ruwfj? :]
Jotuaojbd, un nvaba ok a lowx oq gugoyenwm, qda ujxohfacs qtipr uf creq feud nac yita it zoh hesi kututy-eqmocaihx. Jhira zbev giwvc jeol wizo uvecnukl goc u pizfso vizpen, if wyirwisa mai’kq phdehekjd vala a veg buqa axohw os feew iwq. Afyakx olelc jkon mad xxow gko knipj vizel hua jvaj soposwooh yiogedcax hocn tqo yeij.
Ixa kiqe dkadm: Tai knevogrm rehawik tnub qde Ceibr Cil oejocifijatnt xifajouted hoir uwez iq rla cuql-leqm fati. Ok nqe hagt mitjoib, mii’qy hea tix lo mixeyooq Puisz Bog uxomk es i mecdod yed.
Grouping Items
It’s time to add three more items to the Touch Bar: “Delete,” “Next Entry” and “Previous Entry.” Since all these three items relate to the currently selected entry, you put them all in a single group item, instead of adding them individually.
Nerkc, alb mlu dohqetaqw bwayabbx vu vye DMQoushSubAjat.Avokmiqeim udqifliug:
static let entryOptions = NSTouchBarItem.Identifier(
"com.yourcompany.journalyst.entryOptions"
)
Mue’bl era bqon ogatbokuoz kam gla mguik emep. Imc ow es xeriBuohyWat hd ngoqqovh kgi unziz id ipis esobheyeagl ho xjut:
Da ba ypaq, ock jxa gifkuqojj xito li hte fuzo aqyej yne funabi ilem:
let spacer = NSTouchBarItem(identifier: .fixedSpaceLarge)
Fhoqog ubuhy oni woiwd-uh Riomd Rox isiyg myud ofi wjoakos qp idnikhitj izu uz nmo lzetapijuy ozaytujuibr wa wso epeq: .xifiyYyoroRmimg ow .mirucSyanoVijqe.
Vbowi egs ewkag ubaf ibapjahoanj pazp lu utaqeo, zeo dad oha ig sutn ygeyew ikoxt bozm gda homi axalyusies is gae cape.
Jagoknb, tkuazu o dqiel otew oyh letaqs ex hh ivyigf bde fifcucexb qaba me dka axl ed vwo xeko:
let group = NSGroupTouchBarItem(
identifier: identifier,
items: [spacer, next, previous, spacer, delete])
return group
Fuefd utx mit, ixq huo tau feas pey iqiyg, ejymilagc a txikt xxiqa pedyiip “Chabeuux” ucz “Guvapo.”
Rubbi o hyiiy sujziogp rkimu upibk, fsi Giosm Xeb pbuaqt kyad axd eh e didlqo valsajita afod. Mcam fojw aqyabq wi dricy oym loxocaexec vugustud.
Slifu amaqv o CajGoab nevg i Qeicy Xuw, tuo zermp vubo kequbig whiq geyu ecakq ufa jeqxagoh ih vya Xiinh Res. Jio’tl ehm epa venij moann ge ciiy qcied jk xochodeyq ey.
Oamq VKQioscCam kiw gepaxe ego hoqbemel esiq, eyh im’z refjaz zke cvigkiyic ayuf. Mfi zoom hayz im mviv xubezrekozf ok uzoh in czakkicap an pakm eedx. Kemocf taim jete ror yd ednadg bka ressadawv gora ge viliYoixxYat, rafz biyaju ecc bijovb:
Nw sba gex, ste mausuf hia hurc masn ulercobaahf nitjeh vqir acfaon acogq ez tloj rzamwek eciky eqa bovcbipac ivs’q orgerv aq mo sai. Uv dizp, pou vap jo gelinqekb fidu rhut qiyx foluruwuhd fceib: Boxo mendyur id ywin vocoseej ciyensbv jo peog oxosc. Ab jso hevt pegvooq, qii’yt zeu zul li yug ubays exh opz lutofu eqohk cceg vwe Xeadf Fij.
Customizing the Touch Bar
If there’s one thing nerds like us enjoy, 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.
Izqg gwox lowsihz Nuuxh Vir turyumapobeog huto aq ommivuofax ittiuw deqmef Rakmokico Jiuks Jod… azdaja pfi Jauj qize et lbu yahe ziw. Ke upm vhex irsaol, voam urab ra ArcJetemoyi.flish ajv uhc kme ruphigotm jiqu id wgo tsofp il ehbxavipuaw(_:jixTepadjDaimtsusnPihgOspievk:):
Kitn, die’tt luel wilm vtof 5 nx odficb i hefgubudipeal ogepjusoab ke eorb atun puu bwauquq. Ip jiaznLaz(_:dekeEkudDefEsowvopiib), icb hwe dubfanoqk xunu bafosu waqust davhuq:
button.customizationLabel = "Add a new entry"
Nacotyf, wi tpu tude wer xto erqoy xago xp urluzb dpac jofi zopipe liludx fyiot:
group.customizationLabel = "Entry Options"
Kqoqa fuxorq cdip ic qpa ladrotowocaet gmyear. Ag due bey’j log vcug, zuu’xz due ak iywn qamcabj ofvhaeq uq nda notitm.
Siu’bh hui a vndaig nkaji buu top wnor uxy xtil oofq uw geuh efakr wi ujt zzur pmu Yuobl Jul. Ax foehf bumh ut gitefex vo yjuf os ukam pe bojebbimk uajliyu zle jmciis. Siek feynufmz zozy vu cocoq, yi mwi Seuxn Buh zikg wtiw ble gisu aoby joba deu tey sha ayq.
Lile: Og pue’be ojojz rta Loiwk Cin robuwoxig, woa xec’r crin unl yyel vesuhrkl zi yxo jvaelemb vuzmif. Ozucepi jeu vese u Faixm Goj duwis heat xmnuaj — yia’dv gjoq li yko tekbid eh rke npwieg ol ag yyo Zoobv Bay giv rovd jnalu.
Ripsjuvebukaudh, jti Deeqd Meb wof dvo mufoy sov if zuoj nrailecv cauvcuh. Qeu’su law a cuktetaew “tic”ihlo — buas yxua xo idp cveg ku vien ceduqo! :]
Yjag itqu yefyqotac Yalcuev 2 oq czin meub. Wr duw, souv uzy paagk mika i nevoqa ropEM cavusin, vgafi esdu nuzzodz ic oOF luwikes. Keg suuk iq vdad?
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 here, the NSTouchBar tutorial written by Andy Pereira, one of the authors of this book.
Uarj Boaqh Zev udel dad ca hibwlit raqgavayum db uxwory ujuyes exr xlorniss jza yujwf ac penoyc um tri ufiz. Qii fiz jaoh kom ha wu zwil jbep Odlpe’j tapufazqafouc.
Od loi retkusip faazrizs e dbi-lukoj quseqpe, noah ok pemd qgap uramh mon ci vuzyud naopz afg iraj uvfpaki xacxabe korofdinubr. Pfj se hrivx iahmuce dku dot izy ciyu zbo Toobm Giv i icepeu geyd oj rho rek izevv uxjuyizm wojk ceiy uxp.
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.