多次使用NSApplication runModalForWindow

时间:2015-04-07 10:39:48

标签: cocoa appkit

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

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

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

3 个答案:

答案 0 :(得分:1)

模态窗口的level设置为NSModalPanelWindowLevel。这是一个在普通窗口前面的窗口级别。这就是为什么你不能在窗口B前面放一个窗口A.

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

您可以尝试通过将窗口C级别设置为高于NSModalPanelWindowLevel的某个级别来解决此问题,但在一般情况下可能会出现问题。如果您将级别提高太多,它可能会在系统UI元素前面,如菜单栏或挡板指示器,如音量更改指示器。

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

答案 1 :(得分:0)

简而言之,你有这样的事情:

  1. 删除一些重要数据
  2. 窗口A“删除数据”
  3. 窗口B“您确定要删除数据吗?”
  4. 窗口C“您是否非常确定要删除数据?” (在您要删除数据的过程中渲染A和B无助的旁观者)?
  5. 如果是这样,你可以使用以下两种方法之一:

    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是最直接的方法,没有任何铃声和口哨可能出错。

    编辑道歉,因为MD不喜欢我的代码格式化: - /

答案 2 :(得分:0)

你没有做任何与[NSApplication runModalForWindow:]不合法的事情,并且在正常情况下,窗口C总是在B的前面,而B总是在A的前面。但是,如果你调用orderFront,这可能会令人费解:在windowB上,在这种情况下,窗口被设置为最顶层的窗口。检查你的代码,你可能有一个orderFront:somewhere(或其中一个亲戚:orderFrontRegardless,或orderWindow:relativeTo :)。另一种可能性是可可虫,但这不太可能。