Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa popover处于状态栏时的NSPopover瞬态_Cocoa_Osx Lion_Statusbar_Popover_Nsstatusbar - Fatal编程技术网

Cocoa popover处于状态栏时的NSPopover瞬态

Cocoa popover处于状态栏时的NSPopover瞬态,cocoa,osx-lion,statusbar,popover,nsstatusbar,Cocoa,Osx Lion,Statusbar,Popover,Nsstatusbar,我正在制作一个生活在状态栏中的应用程序。单击状态项时,会弹出NSPopover 看起来是这样的: 问题是:我希望它是“暂时的”,也就是说,如果我点击popover之外的任何地方,它就会关闭。当popover在窗口中时,NSPopoverBehaviorTransient可以正常工作,但当它在状态栏中时,它就不工作了 我自己如何实现这种行为?结果很简单: - (IBAction)openPopover:(id)sender { // (open popover) if(popo

我正在制作一个生活在状态栏中的应用程序。单击状态项时,会弹出NSPopover

看起来是这样的:

问题是:我希望它是“暂时的”,也就是说,如果我点击popover之外的任何地方,它就会关闭。当popover在窗口中时,NSPopoverBehaviorTransient可以正常工作,但当它在状态栏中时,它就不工作了


我自己如何实现这种行为?

结果很简单:

- (IBAction)openPopover:(id)sender
{
    // (open popover)

    if(popoverTransiencyMonitor == nil)
    {
        popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask handler:^(NSEvent* event)
                                    {
                                        [self closePopover:sender];
                                    }];
    }
}

- (IBAction)closePopover:(id)sender
{
    if(popoverTransiencyMonitor)
    {
        [NSEvent removeMonitor:popoverTransiencyMonitor];

        popoverTransiencyMonitor = nil;
    }

    // (close popover)
}

然而,不容易的是,在NSStatusItem中弹出一个popover(当任务控制被调用或空间切换到全屏窗口时,它的行为不符合预期)存在一些令人讨厌的问题。我必须实现一个始终浮动在NSStatusItem上方的自定义窗口,并处理切换到全屏窗口等问题。这似乎很容易,但很明显,状态项并不是为类似的事情而设计的;)

我使用的方法与上述答案类似,只是我将所有内容合并到一个方法中,而不是使用两个单独的iBaction

首先,我声明以下属性

@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];
        }];
    }
}
当用户在视图外单击时,弹出窗口将显示并关闭


请注意,在Interface Builder中,必须将POPOR的行为设置为瞬态,以便用户单击状态项时POPOR将关闭。

要与系统状态项的行为保持一致,请执行以下操作:
添加GlobalMonitorForeventsMatchingMask:nsLeftMousedDownMask | nsrRightMousedDownMask
-以便右键单击也关闭爆米花。