Подход, который я использую, аналогичен приведенному выше ответу, за исключением того, что я объединил все в один метод вместо двух отдельных IBA-операций.
Сначала я объявляю следующие свойства
@property (strong, nonatomic) NSStatusItem *statusItem;
@property (strong, nonatomic) NSEvent *popoverTransiencyMonitor;
@property (weak, nonatomic) IBOutlet NSPopover *popover;
@property (weak, nonatomic) IBOutlet NSView *popoverView;
затем в awakeFromNib я настроил пункт строки состояния
- (void)awakeFromNib {
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
self.statusItem.title = @"Title";
self.statusItem.highlightMode = YES;
self.statusItem.action = @selector(itemClicked:);
}
, за которым следует метод, который вызывается при щелчке элемента строки состояния
- (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];
}];
}
}
, который заставляет всплывающее окно появляться и закрываться, когда пользователь щелкает за пределами представления.
Обратите внимание, что в Интерфейсном Разработчике вы должны установить поведение всплывающего окна на Transient, чтобы всплывающее окно закрывалось, когда пользователь щелкает элемент состояния.