El enfoque que Yo uso es similar a la respuesta anterior, excepto que tengo todo combinado en un método en lugar de utilizar dos IBActions por separado.
En primer lugar, declaro las siguientes propiedades
@property (strong, nonatomic) NSStatusItem *statusItem;
@property (strong, nonatomic) NSEvent *popoverTransiencyMonitor;
@property (weak, nonatomic) IBOutlet NSPopover *popover;
@property (weak, nonatomic) IBOutlet NSView *popoverView;
después en awakeFromNib He definido el elemento de la barra de estado
- (void)awakeFromNib {
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
self.statusItem.title = @"Title";
self.statusItem.highlightMode = YES;
self.statusItem.action = @selector(itemClicked:);
}
seguido por el método que se llama cuando se hace clic en el elemento de la barra de estado
- (void)itemClicked:(id)sender {
[[self popover] showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge];
if (self.popoverTransiencyMonitor == nil) {
self.popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSKeyUpMask) handler:^(NSEvent* event) {
[NSEvent removeMonitor:self.popoverTransiencyMonitor];
self.popoverTransiencyMonitor = nil;
[self.popover close];
}];
}
}
que hace que aparezca el popover y también se cierra cuando el usuario hace clic fuera de la vista.
Tenga en cuenta que en Interface Builder debe establecer el comportamiento del popover en Transient para que el popover se cierre cuando el usuario haga clic en el elemento de estado.
Para un comportamiento consistente con el de los elementos de estado del sistema: 'addGlobalMonitorForEventsMatchingMask: NSLeftMouseDownMask | NSRightMouseDownMask' - para que los clics derechos también cierren el popover. – inket