Showing a popover

It's not unreasonable to want to show an NSPopover from an NSToolbar - probably originating from an item on the toolbar - like this:

Popover from Toolbar Item

Unfortunately, showing a popover in Cocoa relies on the method

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

but as NSToolbarItem inherits from NSObject rather than NSControl (which was possibly a sensible design decision 20 years ago) there's no easy way to get the NSToolbarItem's view - and hence to show the popover from the right place.

The trick is to put an NSButton inside the toolbar item, then use a property to keep track of it, and get its bounds when clicked. The code looks something like :

@property (nonatomic, strong) IBOutlet NSToolbarItem *showPopoverToolbarButton;

and

NSView *viewToShowFrom = [self.showPopoverToolbarButton view];

PopverDetailViewController *pdvc = [[PopoverDetailViewController alloc] initWithNibName:@"PopoverDetailViewController" bundle:nil];

self.popover                       = [[NSPopover alloc] init];
self.popover.contentViewController = pdvc;
self.popover.delegate              = self;
[self.popover showRelativeToRect:[viewToShowFrom bounds] ofView:viewToShowFrom preferredEdge:0];

And there's one more thing. As presented, when clicked the toolbar item will show a nasty light square around itself, like this:

Nasty Light Square

You can get rid of this by changing the button cell type to Momentary Change using Interface Builder.

IBPopover