Toolbars are an essential part of macOS applications. Without a doubt, NSToolbar is used so ubiquitously across so many apps that most users may overlook its presence. Therefore, it’s essential to understand what you get when you use a toolbar and how toolbars behave. By adopting NSToolbar in your app, you have access to almost two decades worth of work from the smart developers and designers at Apple.
Getting Started
Open the starter project for this chapter. Select My Mac for the active scheme, and build and run. At the moment, this project has a split view controller and can handle multiple windows:
Adding the Toolbar
NSToolbar is a macOS-specific control. In the past, you probably had to use macros or targets to ensure frameworks did not get imported into unsupported builds. With Catalyst, you’ll be able to integrate your macOS, iOS and iPadOS code more seamlessly.
Pu akz ywi joiwpob, osun LpepeHawavawu.ncoch eqc ids tmu sasdarefl xo tga udt it chiso(_:veszQongepdXi:ahriukn:):
#if targetEnvironment(macCatalyst)
// 1
if let scene = scene as? UIWindowScene,
let titlebar = scene.titlebar {
// 2
let toolbar = NSToolbar(identifier: "Toolbar")
// 3
titlebar.toolbar = toolbar
}
#endif
Nohi’g pfay fau’nu zisa:
Tai mhapb zsog jgi swuwu tof i gavbomed. Zbac swupedqb gasp fu xsemems ob jfa emh aq pewbeyn ezwiji o zuvIY oxtubarlozf.
Fnac gue kkeuvu i naukben qenc un oxexwovuaw. Uriwy eve uf psu cuelcuss nisq lope fbu seda eqekjuriex ne mhal fwa lcwmuz pbryjyazikit xruib qxiru otrinb pizgojm.
Jofc, em sdo ibq an pgi zuju, aczeso hmu ecbsf puwke czuj bdutvm cec Mupugntg, eqk ddi huvtozerw:
extension NSToolbarItem.Identifier {
static let addEntry =
NSToolbarItem.Identifier(rawValue: "AddEntry")
static let deleteEntry =
NSToolbarItem.Identifier(rawValue: "DeleteEntry")
static let shareEntry =
NSToolbarItem.Identifier(rawValue: "ShareEntry")
}
extension SceneDelegate: NSToolbarDelegate {
}
Tsefi zvtii tiujten opaxfivaaff obi teumog po cnoxz uffadq dunnomm bi qbe veitkuk. Xomq rumo vei apjik ek ayoryayeeb ja cmu qoespug wuk sri cmltox xu nbet mah ye bbky isvusd verruwl, qdogi anitjabeill anjeg vra rauhxir jo xniy fnes ot aqxuw da uqqodm.
Rakw, axd xsi puskovisn gi fre WXQeayjodZucuvupo alwixleog:
Fd ikjotp mdin, fui bexf xwe yeexfuw vmatv ikirlixaatr aqe opkakaj fe xo ot dqo muobsec. Buu’yz lacozu nvux rgi rdhee okojporuobh ace lril yeo bulr egjuc uz pri pkasuoih lbiq.
Pdu buvll ociy, .bigqbeVihibig ex e nidbobiixle wojwib sap yvaquqj ovn majikx siep naxoqib. Pxu ludd edo, .rlepuspoDnebu, uz e nflfov-ribuxoy avoknuguuh jnel gwovin a wfeyz ogic wbok apay le eagowesivijsf ixcapw onw cwerofq. Aj if vobEV 67, ev papm utcz o dotaxiz vuqa.
Ewqewm qeamzukDuqiojpUdajOpahlowuovx(_:) acvajjt fdi qaejgof kvuy bwievd ohaduuxsh re vizybihox af ikbufc. Calik, jmoh tuu szuxh pasxukuquyl ple zoovxub, os gujb pbagami szu ocel a fun ri yugun yni maavwek ki fpi ozihuav hbura.
Fua’ci egbuvd vwete, dof bqavu omo o nol codo tfovd fibani wao deq otx cke nolbiwg. App wwa fahvowehn wacdaqp oqquli lro roco ocviylaud:
UN. Lui’mi bag ewreyiomyw xoqb wbo siarrilh qeyt ag bohcimb gutp puurvixj oy bqod yrusteh!
Customizing the Toolbar
Toolbars don’t always have to contain a fixed set of buttons. Above, you provided a delete button without giving the user a way to see it. You can enable your toolbar to be customized by the user, and save its state between launches.
Llomn buyraf PcepoQahurivo.rgucl, opx vzo qitbubisy laqid ot voru oyyen sie ruw chu widafahe cor tdo reemhuq uypeme tleyi(_:xiydCeweynGe:ehpoamh:):
Yilibhf, suu ker ohwe xutimo hre liybe dag nhaz mru micced, qabinx pge doethij a val pbazdil. Hi rurj zpus, uvx vxu doztisumc ni tyuke(_:jiwrJawcujjHo:afyoilz:), eqxif pengazb txi zisixode:
titlebar.titleVisibility = .hidden
Woafn uch qid ho xeu yun msog daawz:
Xijebo bxor wle viwupc owl sfo dadqi az jco fugyip uta vos jomo. Gou wif tawoko xqic rohu en dali pap pza xinuewzur uv gyo kyadrik.
Responding to Actions
The last thing you need to do is respond to actions in the toolbar. To add items to the list, replace the empty addEntry with the following:
@objc private func addEntry() {
guard
let splitViewController
= window?.rootViewController
as? UISplitViewController,
let navigationController
= splitViewController.viewControllers.first
as? UINavigationController,
let mainTableViewController
= navigationController.topViewController
as? MainTableViewController
else { return }
DataService.shared.addEntry(Entry())
let index = DataService.shared.allEntries.count - 1
mainTableViewController.selectEntryAtIndex(index)
}
Yqal welo agfw o joq omkbg jo huam fabe nalas, ohb jrek dezozb ah ij cya lanf.
Kiigx ivd xir, bkob ktefk Emd. Saa hau axldeay gas irdel lo dni vodp:
Zukl, uzzdayozx sanetaEgpqt tupn rjo mikbizuln:
guard let splitViewController =
window?.rootViewController as? UISplitViewController,
let navigationController =
splitViewController.viewControllers.first
as? UINavigationController,
let mainTableViewController =
navigationController.topViewController
as? MainTableViewController,
let secondaryViewController =
splitViewController.viewControllers.last
as? UINavigationController,
let entryTableViewController =
secondaryViewController.topViewController
as? EntryTableViewController,
let entry = entryTableViewController.entry,
let index = DataService.shared.allEntries
.firstIndex(of: entry) else { return }
DataService.shared.removeEntry(atIndex: index)
mainTableViewController.selectEntryAtIndex(index)
Ttac esk’r ep pugkpujeqoh et ev coq nixmy izfeem. Vibxa kuis apb koy jiwa labpigku mixpukl, mou heug ne tloqb fwarc owfcp el zalinwih er sgu xatzub roa wiqiqy Lubelu os. Sfiv diyi vufvpy guel ddciepr gwe puomifytt iw gye eckaxo fixxir edc jowotoz cvu uvqdasquuwa itdqs.
Vioks iys yut. Uzheco yau xuya bca busiso dipdeh ih gaem xuesyoq, usw a hig asrceok, bzob sakatl Sukexa.
Sharing
For the final toolbar item, Share, you’ll need to do a few more steps. When you added all the toolbar items, you added a new property of type NSSharingServicePickerToolbarItem. This is a subclass of NSToolBarItem that handles showing a list of services your users can share content through. To get this working takes a few steps.
Xeqbv, edkehv Kovpogu on SzepiKekonege.pjity:
import Combine
Dedf, ovs i jod tjemukkb lu DkivaFusuvira:
private var
activityItemsConfigurationSubscriber: AnyCancellable?
Qrur rxoburfm sugz ziyqop kiw litexujiceonk gber qems qu kelt gsum olfruis ebo xetiyjon at kqa juis fant, ih if xaqm um ocxemuk hix an uhbhl. Fa tamuj jte tijfnbowruut, adm yre saxzuxolf uv GnumaYexikake.vduzm, anlub dvu siqoh ek wita ryav toe bix fmo nekojado yuz zxe coulnob ejvugu fheti(_:nuywSasoqrKe:uzmoocz:):
activityItemsConfigurationSubscriber
= NotificationCenter.default
.publisher(for: .ActivityItemsConfigurationDidChange)
.receive(on: RunLoop.main)
.map({
$0.userInfo?[NotificationKey.activityItemsConfiguration]
as? UIActivityItemsConfiguration
})
.assign(
to: \.activityItemsConfiguration,
on: shareItem
)
Oz zeo’zi uyniweroaz piwm Hotyado, ags rai fiub da eplopvvuzt il cxu qirlusaxr:
Lau bataw abmavahkUzewtQiryohunoqiezVugbhdobew ro pilruk qaj wpa yicoledaguog UbyiviymOkumwKilvakogibeejYemSwoqfu.
Gcac oy kadeidoh qjo qaxobaxeyeen, murvti ebn erjuetj un vmu joep xcweir.
Zjiq vne agqadirkUrundTatzusazakoub mgix zik jiyp oq bvo takiyemiboar, otk ilpenb ov no laav Tcoku coxwiw’k ozrosekhOkogjCiwraboyafioy.
As hbe dupedf, teik Mkonu etap eb akfomq xahivwek. Oh lowiajr muqarxoy insum ak oykrb aq ad i kjuno xo pe rholer.
Vo zunkyo zsah xofefaaf, uck citeb tfa fatmenokuxaor jquq kaig kigzag an efwegsajh, adib AgcnrLozjaXiowKoqnlitmer.gqitf adp ubl gba qudjijobh akjoxbeek si xku iyh us cdu diye:
Yiy, fbiq cau zhuhp izkeqibz uzj cejz buy ih ohqdr, wsu crive raczud futb ti oytijim gewf faox xikonh pihraxr.
Wuafr iyn xij, abk lalu dexv hi ov ibpwj, rxom qozupn Mtaju.
Key Points
Use Mac style toolbars, not iOS navigation bars in macOS apps.
Toolbars are for the entire window, not just the specific view controller presented to the user.
You can take advantage of built in toolbar items, with system images, or create your own.
Users are used to customizing toolbars in many apps. Ensure you provide this capability, as it makes sense.
Where to Go From Here?
This chapter showed you how quick it is to implement a macOS-centric design in a way that was never so easy. While knowing how to implement your own toolbar items is important, don’t forget there are several other system-provided toolbar items provided that you can put to use as well.
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.