Skip to content

NSToolbar

Ken Harris edited this page Oct 11, 2020 · 4 revisions

Toolbar items have a "menu form" (menuFormRepresentation), which is normally used for when you shrink the window so there isn't room to display them as normal toolbar items.

  • You should set this! For normal button items, the default is fine. For anything else, you're on your own.

The "menu form" has another (undocumented) use: when the user chooses to display the toolbar as "Text Only", it's not showing the "Icon and Text" toolbar without the icon. It's actually showing the menu form, right in the toolbar.

  • If you're using a validateMenuItem() to update the menu text for an action ("Show"/"Hide", for example), it's not going to get called when you need it to, for the "Text Only" toolbar, because there's no separate "display" step (like normal menus have). In this case, you should just call it something generic like "Toggle" (like the toolbar label, which is shown in the "Icon and Text" view).
    • How can your validateMenuItem() method know which is the toolbar and which is the menubar, if the same action is attached to both? When menuitem.menu==nil, it's the toolbar.

Starting in 10.15, as NSToolbarItemGroup with isBordered = true looks like an NSSegmentedControl. You should also set selectionMode = .momentary to make it act like buttons. You should also set controlRepresentation = .expanded -- otherwise, the customization panel shows it as a blank popup (yuck). Note: unlike using an actual NSSegmentedControl, you don't seem to have control of the tooltip for individual items this way.


NSToolbar changed a lot in 10.15 and 11.0 (and probably other recent versions), and the documentation is especially lacking. Therefore, I have a lot of open questions:

  • How is horizontal sizing determined for the customization palette? No amount of compression resistance on my view can seem to make it anything other than "just a bit narrower than I want". minSize/maxSize are now deprecated. (You can force a required width constraint on the whole view, but that's not really what I want.)

  • How does "Use small size" work? It's clearly not calling NSToolbarDelegate methods again, and it's not updating my frame automatically, so there's some magic notification...

    • UPDATE: the 10.2 release notes (!!) say that if you respond to setControlSize: (or have an NSCell who does), it uses that.
    • Even though 11.0 seems to still include this feature, almost none of Apple's applications keep it enabled (not an option for third-party software), and many of the built-in items (e.g., NSToolbarItemGroup with isBordered=true) don't support it, either. So in practice, your best bet is probably to pretend this doesn't exist -- and file radars telling Apple to either fix it or kill it.
Clone this wiki locally