NSPopover from NSToolbarItem

Recently, when working on the next release of iSMARTtrain, I wanted to display an NSPopover containing the various options when a button in the toolbar was clicked. I mean, how hard can that be? – I’d already done it in the iPad version of Ergophase. Trivial!

NSPopover from NSToolbarItem

Three hours later, it turns out, it’s not as straight-forward as I thought. Central to displaying an NSPopover is the following method call:-

 (void)showRelativeToRect:(NSRect)positioningRect ofView:(NSView *)positioningView preferredEdge:(NSRectEdge)preferredEdge

Surely all I need to do is to get the view from the Toolbar button, pass it to this method, the popover’s displayed, and all is good with the world?

Well, unfortunately not.

For whatever reason, NSToolbarItem is inherited from NSObject, rather than NSControl, meaning that it has no View property that can be accessed (well, actually it does, but for the default button added in IB, view always returns Nil).

I posted my problem in Stackoverflow and, unusually, got no solution. Searching Apple’s developer forums turned up this post (http://devforums.apple.com/message/499986), which refered me to one of this year’s WWDC videos.

Once I’d seen that, everything became a bit clearer. The solution is to create an NSToolbarItem with a custom view containing an NSButton. When the button is clicked, pass the View of the button to the showRelativeToRect method, displaying the popover.

In the spirit of  http://xkcd.com/979, I’m posting a really simple example with the code on github (http://github.com/tevendale/ToolbarPopover). One slight issue with the current code is the way the button behaves when clicked, but I’m sure someone smarter than me will manage to fix that.

This entry was posted in Cocoa. Bookmark the permalink.

2 Responses to NSPopover from NSToolbarItem

  1. Winston Smith says:

    You can fix the button flash by changing the button cell type to “Momentary Change” in IB.

  2. tevendale says:

    Thanks for that – I’ll give it a go.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s