4

我正在玩一个想法,基本上我想要一个带有 NSPopoverController 的 NSStatusItem。我阅读了人们遇到的所有问题,但我只是想尝试一下。现在有干净的方法吗?我见过的所有版本都至少有 1 年的历史并且 suuuuper hacky。

到目前为止,这是我的方法,但是如果我在状态栏中单击我的应用程序,则没有任何反应...

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];

    //[self.statusItem setView:view];
    [self.statusItem setTitle:@"Test"];
    [self.statusItem setHighlightMode:YES];
    [self.statusItem setAction:@selector(activatePopover:)];

}


-(IBAction)activatePopover:(id)sender
{
    BOOL isEnabled = NO;

    if (isEnabled) {
        [self.popover showRelativeToRect:NSMakeRect(0, 0, 50, 50) ofView:statusItem.view preferredEdge:NSMinYEdge];

    } else {
        [self.popover close];
    }
}

任何想法如何让它运行?

谢谢

4

2 回答 2

7

如果不对状态项使用自定义视图,这将不起作用。如果您不设置自定义视图,则该view属性将为空(它只返回自定义视图,而不是NSStatusItem您使用时内部使用的任何视图setTitle)。

不幸的是,根据 Apple 的文档,如果您想使用NSPopover.

我还没有看到包含正确处理此问题的完整示例(状态项的默认实现相当多,您必须手动完成所有操作),并且还修复了弹出框的错误:

  • NSPopover,默认情况下,不会成为关键窗口(某些控件不起作用),除非您覆盖canBecomeKeyWindowNSPopover 的窗口
  • 正确关闭其他状态项的菜单(您可以popUpStatusItemMenu使用空菜单调用以正确聚焦您的状态项)
  • 绘制突出显示的背景drawStatusBarBackgroundInRect
  • 对鼠标左键和右键单击都有反应
  • NSRunningApplication.currentApplication.activateWithOptions用于确保您的状态项的所有窗口都变为活动状态(否则您的弹出窗口将不正常地不是键盘输入的接收器)
  • 关闭 NSPopover NSEvent.addGlobalMonitorForEventsMatchingMask(内置的关闭机制弹出框不适用于状态项)
  • 删除终止时的状态项NSStatusBar.systemStatusBar.removeStatusItem

我希望很快能有一篇关于这个的博客文章(注意:我使用的是 RubyMotion,而不是 Objective-C),它解释了所有这些问题,并希望为创建菜单提供一个更简单的基础。如果我写那篇文章,我会更新这条评论。

于 2014-05-04T12:31:23.780 回答
2

代码:

-(void)initializeStatusBarItem
{
    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
    NSImage* image = [NSImage imageNamed:@"image"];
//    [image setTemplate:YES];
    self.statusItem.button.image = image;
    self.statusItem.highlightMode = NO;
    self.statusItem.button.action = @selector(statusBarItemDidClick:);
}

- (void)statusBarItemDidClick:(NSStatusBarButton *)sender{
    MainViewController *mainView = [[MainViewController alloc] init];
    self.popoverView = [[NSPopover alloc] init];
    [self.popoverView setContentViewController:mainView];
    self.popoverView.contentSize = CGSizeMake(300, 400);
    self.popoverView.behavior = NSPopoverBehaviorTransient;
    [self.popoverView showRelativeToRect:sender.bounds ofView:sender preferredEdge:NSMaxYEdge];
}
于 2015-10-31T15:23:14.583 回答