我想知道是否允许使用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()?
答案 0 :(得分:1)
模态窗口的level
设置为NSModalPanelWindowLevel
。这是一个在普通窗口前面的窗口级别。这就是为什么你不能在窗口B前面放一个窗口A.
但是,窗口B和C都处于同一级别。因此,窗口服务器不会强制窗口C始终位于窗口B的前面。
您可以尝试通过将窗口C级别设置为高于NSModalPanelWindowLevel
的某个级别来解决此问题,但在一般情况下可能会出现问题。如果您将级别提高太多,它可能会在系统UI元素前面,如菜单栏或挡板指示器,如音量更改指示器。
您还可以使用addChildWindow(_:ordered)
使窗口C成为窗口B的子窗口。这将强制执行指定的排序。它确实有一些副作用。例如,如果移动窗口B,窗口C也会移动,以保持相对定位相同。
答案 1 :(得分:0)
简而言之,你有这样的事情:
如果是这样,你可以使用以下两种方法之一:
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 :)。另一种可能性是可可虫,但这不太可能。