J'utilise est similaire à la réponse ci-dessus, sauf que j'ai tout combiné en une seule méthode au lieu d'utiliser deux IBActions distinctes.
D'abord, je déclare les propriétés suivantes
@property (strong, nonatomic) NSStatusItem *statusItem;
@property (strong, nonatomic) NSEvent *popoverTransiencyMonitor;
@property (weak, nonatomic) IBOutlet NSPopover *popover;
@property (weak, nonatomic) IBOutlet NSView *popoverView;
puis dans awakeFromNib Je mis en place l'élément de barre d'état
- (void)awakeFromNib {
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
self.statusItem.title = @"Title";
self.statusItem.highlightMode = YES;
self.statusItem.action = @selector(itemClicked:);
}
suivi de la méthode qui est appelée lorsque l'élément de la barre d'état est cliqué
- (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];
}];
}
}
qui fait apparaître le popover et se ferme également lorsque l'utilisateur clique en dehors de la vue.
Notez que dans Interface Builder, vous devez définir le comportement du popover sur Transient pour que le popover se ferme lorsque l'utilisateur clique sur l'élément d'état.
Pour un comportement cohérent avec celui des éléments d'état du système: 'addGlobalMonitorForEventsMatchingMask: NSLeftMouseDownMask | NSRightMouseDownMask' - de sorte que les clics droits ferment également le popover. – inket