我花了相当多的实验来消除对 Objective-C 的ModalForWindow"语言的一些困惑,以及随后如何使用模态会话.也许以下提示可以节省一些时间:
It took me quite a bit of experimentation to clear up some confusion over Objective-C’s "ModalForWindow" language and, subsequently, how to use a modal session. Maybe the following tips will save somebody some time:
(如果您不熟悉这个概念:当窗口(通常是面板)运行模式时,它会阻止应用程序的其他部分响应,直到它被关闭.)
(In case you’re new to the concept: When a window, usually a panel, runs modal, it prevents some other part of the app from responding until it has been dismissed.)
ModalForWindow"在不同的情况下有不同的含义.如果您使用 loadNibNamed 来显示由 xib 定义的面板,并且希望它运行模式,请在显示后调用它:
"ModalForWindow" means different things in different circumstances. If you are using loadNibNamed to display a panel defined by a xib and you want it to run modal, call this once it is displayed:
// Make panelReviewImports modal, so that no other part of app will respond.
[[NSApplication sharedApplication] runModalForWindow:self.panelReviewImports];
并在其解雇方法中跟进:
and follow up with this in its dismissal methods:
[[NSApplication sharedApplication] stopModal];
但是对于 NSAlert,beginSheetModalForWindow 中的窗口"指的是作为工作表附加警报的窗口,该窗口将被冻结直到警报被解除.但应用不会被冻结;所有其他窗口将保持可操作.如果您想将警报作为工作表附加并且还冻结应用程序的其余部分,按照 beginSheet 代码调用 runModal 并明确使用返回代码,如下所示:
But for NSAlert, the "window" in beginSheetModalForWindow refers to the window to which the alert will be attached as a sheet, which window will be frozen until the alert is dismissed. But the app won’t be frozen; all other windows will remain operable. If you want to attach an alert as a sheet and also freeze the rest of the app, follow the beginSheet code with a simple call to runModal and use the return code explicitly, like this:
[alert beginSheetModalForWindow:self.window
modalDelegate:self didEndSelector:@selector(abandonmentAlertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
NSInteger returnCode = [alert runModal];
[self abandonmentAlertDidEnd:alert returnCode:returnCode contextInfo:nil];
(当然,你已经实现了abandonmentAlertDidEnd:returnCode:contextInfo: 代码作为类方法.)
(Of course, you will have implemented the abandonmentAlertDidEnd:returnCode:contextInfo: code as a class method.)
或者,如果您希望警报作为居中面板运行,请单独调用 runModal.
Or, if you want the alert to run as a centered panel, call runModal by itself.
假设您要运行一个面板模式,如果用户提交了无效条目,则随后会发出警报.您必须在显示警报之前停止Modal——之后,由于某种原因,另一个对 runModalForWindow 的调用无法正常工作.对于这种情况,您需要一个模态会话:
Suppose you want to run a panel modal, followed by an alert if the user submits an invalid entry. You’d have to stopModal before you show the alert — after which, for some reason, another call to runModalForWindow fails to work properly. For this scenario, you need a modal session:
1) 将 NSModalSession 属性添加到您的控制器类,因为 modalSession 必须可以跨多个方法访问.
1) Add an NSModalSession property to your controller class, because the modalSession must be accessible across multiple methods.
2) 显示面板后,调用 beginModalSessionForWindow 实例化 modalSession:
2) Once you have displayed the panel, call beginModalSessionForWindow to instantiate the modalSession:
self.modalSession = [[NSApplication sharedApplication] beginModalSessionForWindow:self.panelForInput];
3) 用一个调用 runModalSession 的 while 循环跟进,当它的返回不等于 NSRunContinuesResponse 时中断:
3) Follow this up with a while-loop that calls runModalSession, breaking when its return does not equal NSRunContinuesResponse:
while ([[NSApplication sharedApplication] runModalSession:self.modalSession] == NSRunContinuesResponse)
continue;
当用户单击面板上的一个按钮时,循环将中断,应用程序将被释放.(在面板的文本字段中键入将使模态会话保持不变.)
The loop will break and the app will free up when the user clicks on one of the panel’s buttons. (Typing in the panel’s textfield will leave the modal session intact.)
4) 在你的按钮处理中,如果用户的输入无效,你用 runModal 调用一个警报.
4) In your button handling, if the user’s entry is invalid, you call an alert with runModal.
5) 在警报调用的正下方,在警报解除后将执行的代码中,您放置了上面使用的相同 while 循环.面板的模态会话继续.
5) Immediately below the alert call, in the code which will execute once the alert is dismissed, you put the same while-loop used above. The panel’s modal session resumes.
6) 在您处理关闭面板时,无论是在有效进入还是取消时,您都会调用 endModalSession,奇怪的是,这还不够;即使您从未调用过 runModalForWindow,您也必须调用 stopModal.
6) In your handling to close the panel, either upon valid entry or cancel, you call endModalSession, which, oddly, isn’t enough; you must also call stopModal, even though you never called runModalForWindow.
[[NSApplication sharedApplication] endModalSession:self.modalSession];
[[NSApplication sharedApplication] stopModal];
[self.panelForInput close];
问题就是答案.我只是发布这个来关闭它.很抱歉扭曲了 stackoverflow 格式.
The question is the answer. I'm just posting this to close it out. Sorry for twisting the stackoverflow format.
这篇关于NSApp 的 ModalForWindow、NSAlert 的 ModalForWindow 和 ModalSession 的小技巧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!