【问题标题】:Using NSApplication runModalForWindow multiple times多次使用 NSApplication runModalForWindow
【发布时间】:2015-04-07 10:39:47
【问题描述】:

我想知道是否允许使用 runModalForWindow() 启动多个模态循环。在我的应用程序中,我有以下设置:当用户在非模态窗口 A 中按下按钮 A 时,将使用 runModalForWindow() 打开模态窗口 B。在模态窗口B中,有一个按钮B。如果用户按下这个按钮B,将使用runModalForWindow()打开模态窗口C。当模态窗口 C 打开时,将阻止窗口 A 和 B 进行用户输入,而当模态窗口 B 打开时,将阻止窗口 A。

这种方法与 runModalForWindow() 一起使用,但我遇到了一个小问题,这让我想知道我在这里做的事情是否被允许。当模态窗口 C 打开时,我实际上可以将模态窗口 B 移动到模态窗口 C 的前面。B 不接受任何输入,但它实际上可以移动到 C 的前面。但是,窗口 A 永远不能移动到前面B(或 C)...它总是留在后台。

有谁知道为什么 B 可以移动到 C 前面而 A 永远不能移动到 B 或 C 前面?是否允许多次使用runModalForWindow()?

【问题讨论】:

    标签: cocoa appkit


    【解决方案1】:

    模态窗口的level 设置为NSModalPanelWindowLevel。这是在普通窗户前面的窗户水平。这就是为什么不能将窗口 A 放在窗口 B 前面的原因。

    但是,窗口 B 和 C 都处于同一级别。因此,窗口服务器不会强制窗口 C 总是在窗口 B 前面。

    您可以尝试通过将窗口 C 的级别设置为高于NSModalPanelWindowLevel 的值来解决此问题,但在一般情况下这可能会出现问题。如果您将级别提高太多,它可能会出现在系统 UI 元素之前,例如菜单栏或边框指示器(例如音量变化指示器)。

    您还可以使用addChildWindow(_:ordered) 使窗口 C 成为窗口 B 的子窗口。这将强制执行指定的顺序。它确实有一些副作用。例如,如果您移动窗口 B,则窗口 C 也会移动,以保持相对位置不变。

    【讨论】:

      【解决方案2】:

      总之你有这样的东西:

      1. 删除一些重要数据
      2. 窗口 A“删除数据”
      3. 窗口 B“确定要删除数据吗?”
      4. 窗口 C “您非常非常确定要删除数据吗?” (在您寻求删除数据的过程中让 A 和 B 成为无助的旁观者)?

      如果是这样,您可以使用以下两种方法之一:

      1) 使用完成的 NSAlert

      //ALERT A
      [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
          //handle the response!
          //ALERT B
          [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
              //handle the response!
              //ALERT C
              [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
                  //handle the final responde
              }];
          }];
      }];
      

      2) 使用完成块的模态窗口(参见上一个:Custom Modal Window with Block Completion Handler

      i.e. When A closes, handler calls B, when B closes, handler called C etc... all serially
      

      我个人喜欢 (2) 的外观,但 1 是最直接的方法,没有任何可能出错的花里胡哨。

      edit 抱歉,因为 MD 不喜欢我的代码格式:-/

      【讨论】:

        【解决方案3】:

        你没有在[NSApplication runModalForWindow:]做任何不合法的事情,并且在正常情况下,窗口C总是在B前面,B总是在A前面。但是如果你打电话给orderFront:,这可能会很复杂在 windowB 上,在这种情况下,窗口被设置为最顶层。

        检查您的代码,您可能在某处有一个orderFront:(或其亲属之一:orderFrontRegardlessorderWindow:relativeTo:)。另一种可能性是可可虫,但这不太可能。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多