【问题标题】:NSPopover and adding spacing with NSStatusItemNSPopover 并使用 NSStatusItem 添加间距
【发布时间】:2025-11-22 10:45:01
【问题描述】:

我正在开发一个使用NSPopover 的菜单栏应用程序。我正在使用以下代码来呈现弹出框。

[self.mainPopover showRelativeToRect:[testView bounds] ofView:testView preferredEdge:NSMinYEdge];

问题是它离状态栏太近了,如下所示。

即使我更改了矩形,它也没有任何效果,而且正如文档所述,这是正确的

定位视图中的矩形,弹出框应相对于其定位。通常设置为定位视图的边界。可能是一个空矩形,默认为positioningView的边界。

以下是 Dropbox 应用程序的屏幕截图,我只是想知道如何在我的应用程序中添加一些间距,例如 Dropbox。

【问题讨论】:

    标签: objective-c macos nsstatusitem nspopover


    【解决方案1】:

    为了实现这一点,我添加了一个填充视图并将集合 NSStatusItem 视图附加到该容器视图。所用解决方案的代码如下,供任何希望实施它的人使用。

    _paddingView = [NSView new];
    [_containerView addSubview:_paddingView];
    [_containerView addSubview:_dragView];
    
    [_dragView      setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_paddingView   setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_dragView(22)][_paddingView(5)]|"                                                                                                                 options:0
                                                                           metrics:nil views:views]];
    [_containerView addConstraint:[NSLayoutConstraint constraintWithItem:_dragView
                                                               attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
                                                                  toItem:_paddingView attribute:NSLayoutAttributeLeft
                                                              multiplier:1. constant:0]];
    [_containerView addConstraint:[NSLayoutConstraint constraintWithItem:_dragView
                                                               attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
                                                                  toItem:_paddingView attribute:NSLayoutAttributeRight
                                                              multiplier:1. constant:0]];
    
    self.mainPopover = [[NSPopover alloc] init];
    self.mainPopover.delegate = self;
    self.mainPopover.backgroundColor = [NSColor greenColor];
    [self.mainPopover setAnimates:NO];
    [self.mainPopover setBehavior:NSPopoverBehaviorTransient];
    [self.mainPopover setContentViewController:viewController];
    
    [_containerView layoutSubtreeIfNeeded];
    
    [_statusItem setView:_containerView];
    

    【讨论】:

    【解决方案2】:

    您可以插入测试视图边界以在 de view 和 popover 之间添加一些边距:

    NSPopover *mainPopover = [self mainPopover];
    NSRect bounds = CGRectInset([testView bounds], -50.0, -50.0);
    [mainPopover showRelativeToRect:bounds ofView:testView preferredEdge:NSMinYEdge];
    

    【讨论】:

    • 这不起作用,因为文档状态 postioningrect 是定位视图中的矩形
    • 它适用于我放置在窗口内的 NSButton,但我猜 NSMenuItemButton 的包含窗口不允许它超出范围。
    • 我必须在实际视图下方布置一个不可见的视图来实现这一点。
    • 有同样的想法,似乎是唯一的解决方案。根据我在 Mac 开发方面的经验,有时 hacky 解决方案是唯一的解决方案。
    • @Pier 让我这样做