多次使用 NSApplication runModalForWindow
Using NSApplication runModalForWindow multiple times
我想知道是否允许使用 runModalForWindow() 启动多个模态循环。在我的应用程序中,我有以下设置:当用户在非模态 window A 中按下按钮 A 时,模态 window B 将使用 runModalForWindow() 打开。在模态 window B 中,有一个按钮 B,如果用户按下这个按钮 B,将使用 runModalForWindow() 打开模态 window C。当模态 window C 打开时,windows A 和 B 应阻止用户输入,当模态 window B 打开时,window A 应被阻止。
这种方法与 runModalForWindow() 一起使用,但我遇到了一个小问题,这让我想知道我在这里做的事情是否被允许。当 modal window C 打开时,我实际上可以将 modal window B 移动到 modal window C 的前面。B 不接受任何输入,但它实际上可以移动到 C 的前面. Window 但是,A 永远无法移动到 B(或 C)的前面...它始终处于后台。
有没有人知道为什么 B 可以移到 C 的前面,而 A 永远不能移到 B 或 C 的前面?是否允许多次使用 runModalForWindow()?
所以简而言之,你有这样的东西:
- 删除一些重要数据
- Window一个"Delete Data"
- Window乙"Are you sure you want to delete the data?"
- Window C "Are you VERY VERY sure you want to delete the data?"(让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) 模态 window 使用完成块(参见前面的: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 不喜欢我的代码格式:-/
模态 window 的 level
设置为 NSModalPanelWindowLevel
。这是一个 window 级别,高于正常 windows。这就是为什么你不能把 window A 放在 window B 前面。
但是,windowsB和C是同级别的。因此,window 服务器不会强制 window C 总是在 window B 之前。
您可以尝试通过将 window C 的级别设置为高于 NSModalPanelWindowLevel
的级别来解决此问题,但在一般情况下这可能会出现问题。如果您将级别提高太多,它可能最终会出现在系统 UI 元素的前面,例如菜单栏或边框指示器(例如音量变化指示器)。
您还可以使用 addChildWindow(_:ordered)
使 window C 成为 window B 的子代。这将强制执行指定的顺序。它确实有一些副作用。例如,如果您移动 window B,window C 也会移动,以保持相对定位不变。
你没有做任何与 [NSApplication runModalForWindow:]
不合法的事情,在正常情况下 window C 总是在 B 前面,B 总是在 A 前面。但是这可以如果你在 windowB 上调用 orderFront:
会很复杂,在这种情况下 window 被设置为最上面的一个。
检查你的代码,你可能在某处有一个 orderFront:
(或者它的一个亲戚:orderFrontRegardless
,或 orderWindow:relativeTo:
)。另一种可能性是 cocoa 错误,但这种可能性不大。
我想知道是否允许使用 runModalForWindow() 启动多个模态循环。在我的应用程序中,我有以下设置:当用户在非模态 window A 中按下按钮 A 时,模态 window B 将使用 runModalForWindow() 打开。在模态 window B 中,有一个按钮 B,如果用户按下这个按钮 B,将使用 runModalForWindow() 打开模态 window C。当模态 window C 打开时,windows A 和 B 应阻止用户输入,当模态 window B 打开时,window A 应被阻止。
这种方法与 runModalForWindow() 一起使用,但我遇到了一个小问题,这让我想知道我在这里做的事情是否被允许。当 modal window C 打开时,我实际上可以将 modal window B 移动到 modal window C 的前面。B 不接受任何输入,但它实际上可以移动到 C 的前面. Window 但是,A 永远无法移动到 B(或 C)的前面...它始终处于后台。
有没有人知道为什么 B 可以移到 C 的前面,而 A 永远不能移到 B 或 C 的前面?是否允许多次使用 runModalForWindow()?
所以简而言之,你有这样的东西:
- 删除一些重要数据
- Window一个"Delete Data"
- Window乙"Are you sure you want to delete the data?"
- Window C "Are you VERY VERY sure you want to delete the data?"(让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) 模态 window 使用完成块(参见前面的: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 不喜欢我的代码格式:-/
模态 window 的 level
设置为 NSModalPanelWindowLevel
。这是一个 window 级别,高于正常 windows。这就是为什么你不能把 window A 放在 window B 前面。
但是,windowsB和C是同级别的。因此,window 服务器不会强制 window C 总是在 window B 之前。
您可以尝试通过将 window C 的级别设置为高于 NSModalPanelWindowLevel
的级别来解决此问题,但在一般情况下这可能会出现问题。如果您将级别提高太多,它可能最终会出现在系统 UI 元素的前面,例如菜单栏或边框指示器(例如音量变化指示器)。
您还可以使用 addChildWindow(_:ordered)
使 window C 成为 window B 的子代。这将强制执行指定的顺序。它确实有一些副作用。例如,如果您移动 window B,window C 也会移动,以保持相对定位不变。
你没有做任何与 [NSApplication runModalForWindow:]
不合法的事情,在正常情况下 window C 总是在 B 前面,B 总是在 A 前面。但是这可以如果你在 windowB 上调用 orderFront:
会很复杂,在这种情况下 window 被设置为最上面的一个。
检查你的代码,你可能在某处有一个 orderFront:
(或者它的一个亲戚:orderFrontRegardless
,或 orderWindow:relativeTo:
)。另一种可能性是 cocoa 错误,但这种可能性不大。