简体   繁体   English

NSPopover 以分离状态启动

[英]NSPopover to start in a detached state

Is there a way to force the NSPopover to start in the detached state?有没有办法强制 NSPopover 在分离状态下启动? I only see isDetached which is a read-only property for the state of the popover and an NSPopoverDelegate method detachableWindow(forPopover:) which lets me override the window that gets created.我只看到isDetached它是弹出窗口状态的只读属性和一个 NSPopoverDelegate 方法detachableWindow(forPopover:) ,它让我覆盖创建的窗口。 I'd like to essentially click a button and have the NSPopover start in the state in this photo.我想基本上单击一个按钮并让 NSPopover 以这张照片中的状态启动。

The style of this window is exactly what a product requirement is and I can't seem to find any NSWindow style settings that would make a window do something like this (nor an NSPanel)这个窗口的样式正是产品要求的样子,我似乎找不到任何 NSWindow 样式设置可以让窗口做这样的事情(也不是 NSPanel)

This detached popover functionality seems special in that it:这种分离的弹出窗口功能似乎很特别,因为它:

  1. non-modal, but stays above main app.非模态,但保持在主应用程序之上。 Able to still interact with the main app just like in Messages how you can still click around and type a new message.仍然可以像在消息中一样与主应用程序交互,您仍然可以单击并键入新消息。
  2. Clicking another app, AppFoo, puts both the main app and the helper window behind AppFoo.单击另一个应用程序 AppFoo,会将主应用程序和帮助程序窗口置于 AppFoo 后面。
  3. The helper window can be moved around and isn't hidden on app deactivation (another app gets selected).助手窗口可以四处移动并且不会在应用程序停用时隐藏(另一个应用程序被选中)。
  4. Has the little, native, grey X in the top left.左上角有一个小的、原生的、灰色的 X。

从消息中的详细信息按钮分离 NSPopover

If you don't mind calling private API, it's actually pretty simple:如果您不介意调用私有 API,它实际上非常简单:

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

No need to even add a delegate.甚至不需要添加委托。 I don't know when this private method was added but it's available at least since macOS 10.13.我不知道这个私有方法是什么时候添加的,但至少从 macOS 10.13 开始就可以使用了。 I suspect it's available since the introduction of NSPopover , though.不过,我怀疑自从引入NSPopover它就可用了。

Here is the trick.这是诀窍。 Use the required delegate method detachableWindowForPopover: to do the work for you, like:使用所需的委托方法detachableWindowForPopover:为您完成工作,例如:

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

    [detachedWindow.windowController showWindow:nil];
}

Seems that the Apple engineers implemented detachableWindowForPopover: on a pretty smart way, I guess it uses the content view controller class, and will always create a singleton like instance of the detached window.似乎 Apple 工程师实现了detachableWindowForPopover:以一种非常聪明的方式,我猜它使用了内容视图控制器类,并且总是会创建一个像分离窗口的实例一样的单例。 Once detachableWindowForPopover: has called the presented window instance will be re-used no matter when and why it is called, called it directly (from a func like my sample above) or indirectly (eg when you drag out, detach, the popover from its original position)一旦detachableWindowForPopover:调用了所呈现的窗口实例,无论何时以及为何调用它,都会重新使用它,直接(从上面的示例中的 func 中)或间接调用它(例如,当您从其拖出、分离、弹出窗口时原来的位置)

This way they can prevent a popover being detached 'twice' and we can also implement the detached way programmatically, nice job from them!通过这种方式,他们可以防止弹出窗口被“两次”分离,我们还可以通过编程实现分离方式,他们做得很好!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM