如何使NSPopover的分离窗口成为模态窗口

时间:2012-01-13 02:09:19

标签: objective-c macos modalviewcontroller nswindow

在MAC OS X 10.7中,Apple引入了一个名为NSPopover的新类,您甚至可以将该弹出视图拖出来成为一个独立的NSWindow。但是,我想阻止用户与主窗口的交互,直到分离的窗口关闭。我怎样才能安全地做到这一点?

实际上,一个更常见(甚至更愚蠢)的问题应该是,如何在当前前窗返回之前阻止任何用户交互?我也很喜欢编程。

1 个答案:

答案 0 :(得分:3)

我自己找到了解决方案。它现在看起来很好。

要做到这一点,在将分离的窗口排序到前面并成为关键窗口之后,以下代码将使其成为模态窗口(其中currModalSession是我自己定义的iVar)。

- (void)windowDidBecomeKey:(NSNotification *)notification {
    if (notification.object == detachedWindow) {
        if (!detachedWindow.isModalPanel) {
            currModalSession = [NSApp beginModalSessionForWindow:detachedWindow];
            [NSApp runModalSession:currModalSession];
        }
    }
}

此外,您必须结束已打开的每个模态会话。所以下面的代码完成了这项工作:

- (void)windowWillClose:(NSNotification *)notification {
    if (notification.object == detachedWindow) {
        if (currModalSession) {
            [NSApp endModalSession:currModalSession];
        }
    }
}

注意:你必须在这里使用模态会话而不是runModalForWindow有两个原因:

  1. 否则主窗口不会立即被阻挡。我还没有明白理由。一种可能的解释是:runModalForWindow不仅会阻止用户交互,还会阻止内部通信,因此主窗口可能需要更多时间才能准备就绪。
  2. 如果你计划从分离的窗口运行另一个框架模式对话框(例如NSOpenPanel),当返回时,分离的窗口将成为新模式对话框关闭之前的关键窗口,即runModalForWindow将冻结另一个关闭窗口。这意味着关闭窗口将不会关闭。