NSPopover 以分离状态启动

NSPopover to start in a detached state

有没有办法强制NSPopover在分离状态下启动?我只看到 isDetached,它是弹出窗口状态的只读 属性 和 NSPopoverDelegate 方法 detachableWindow(forPopover:),它让我覆盖创建的 window。我想基本上单击一个按钮并让 NSPopover 以这张照片中的状态启动。

这个 window 的风格正是产品要求,我似乎找不到任何 NSWindow 风格设置可以让 window 做这样的事情(也不是 NSPanel )

这个独立的弹出窗口功能看起来很特别,因为它:

  1. 非模态,但保持在主应用程序之上。仍然可以像在消息中一样与主应用程序交互,您仍然可以点击并输入新消息。
  2. 单击另一个应用程序 AppFoo,会将主应用程序和辅助程序 window 置于 AppFoo 之后。
  3. 助手 window 可以四处移动,并且不会在应用停用时隐藏(选择另一个应用)。
  4. 在左上角有一个小的、原生的、灰色的 X。

这是诀窍。 使用所需的委托方法 detachableWindowForPopover: 为您完成工作,例如:

- (void) showPopoverDetached
{
    NSWindow* detachedWindow = [self detachableWindowForPopover:nil];

    [detachedWindow.windowController showWindow:nil];
}

似乎 Apple 工程师以一种非常聪明的方式实现了 detachableWindowForPopover:,我猜它使用了内容视图控制器 class,并且总是会创建一个独立的 [=22] 类实例=]. 一旦 detachableWindowForPopover: 调用了呈现的 window 实例,无论何时以及为何调用它,直接调用它(从像我上面的示例的函数)或间接调用它(例如,当你拖出, 从原来的位置分离弹出窗口)

这样他们可以防止弹出窗口被分离'twice',我们也可以通过编程实现分离方式,他们做得很好!

如果你不介意调用private API,其实很简单:

let detach = NSSelectorFromString("detach")
if popover.responds(to: detach) {
    popover.perform(detach)
}

甚至不需要添加委托。我不知道这个私有方法是什么时候添加的,但它至少从 macOS 10.13 开始可用。不过,我怀疑自 NSPopover 推出以来它就可用了。