【问题标题】:NSPopover to start in a detached stateNSPopover 以分离状态启动
【发布时间】:2018-06-25 21:00:34
【问题描述】:

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

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

这种分离的弹出框功能似乎很特别:

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

【问题讨论】:

    标签: swift macos cocoa nswindow nspopover


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      这样他们可以防止弹出框被“两次”分离,我们还可以以编程方式实现分离的方式,他们做得很好!

      【讨论】:

      • 我对 mac dev 还很陌生,我不太了解解决方案。我已经实现popoverShouldDetach 以在我的NSPopoverDelegate 中返回true,并且我可以拖动我的弹出框以将其与最初附加到的选定NSView 分离(使用popover.show(relativeTo ...)。但是直接调用detachableWindowForPopover 意味着我需要在我的popover 委托中实现它,对吗?目前它被简单地实现为return nil
      • 形成detachableWindowForPopover的帮助:“如果没有delegate,delegate没有实现这个方法,或者delegate返回nil,弹窗不会分离显示。”所以,是的,您必须实现委托方法,当用户将弹出框从其初始“状态”拖出时将调用它,您也可以随时调用它以最初以分离状态显示它
      • 我也无法让建议生效。它所要做的就是弹出一个与弹出窗口无关的附加窗口。在 10.14 测试
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多