- (IBAction)accountButtonPressed:(id)sender {
[NSApp beginSheet:self.accountSheet
modalForWindow:[mainWindowView window]
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
[NSApp runModalForWindow:self.accountSheet];
[NSApp endSheet:self.accountSheet];
[self.accountSheet orderOut:self];
}
哇,看着那个,截图看起来像这样也就不足为奇了。
让我们一次走过这一行。当您单击“帐户”按钮时,您会立即连续执行 4 件事:
您正在告诉应用程序开始显示附加到主窗口的工作表。这没关系,实际上是您在该accountButtonPressed:
方法中想要的唯一代码。
在开始该工作表之后,您告诉应用程序您还希望以应用程序模式的方式单独显示该工作表(不附加到任何窗口,而是在屏幕中间),这会阻止所有其他事件在应用程序中处理。换句话说,这条线并没有真正的意义。您可以以“文档模式”方式(仅绑定该工作表所附加到的窗口)或以“应用程序模式”方式将窗口显示为工作表,但不能同时显示两者。;-)
刚展示完表格后,您立即告诉NSApp
停止展示表格。现在,您确实希望最终做到这一点,但是在刚刚显示它 0.0005 秒后关闭工作表可能会让您的用户有点沮丧。
您现在告诉工作表隐藏自己。这需要从您的didEndSelector:
方法中完成,这将我们带到您的第一种方法中的问题。
-
[NSApp beginSheet:self.accountSheet
modalForWindow:[mainWindowView window]
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
这很好,但请阅读文档beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:
以及工作表编程主题:使用自定义工作表。(Class Reference 页面顶部的 Companion guides 链接对于学习如何在现实世界中使用 API 特别有帮助。它们在我学习时非常有帮助)。
指定当工作表停止显示时nil
,modalDelegate:
您没有任何等待通知的信息(当您调用 时会发生这种情况[NSApp endSheet:sheet]
)。您还没有指定@selector
要在工作表结束时调用的方法。选择器有点像函数,也就是“方法”。
您的代码应如下所示:
@implementation MDAppDelegate
- (IBAction)showSheet:(id)sender {
[NSApp beginSheet:self.sheet
modalForWindow:self.window
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:NULL];
}
- (IBAction)cancel:(id)sender {
[NSApp endSheet:self.sheet];
}
- (IBAction)ok:(id)sender {
[NSApp endSheet:self.sheet];
}
- (void)sheetDidEnd:(NSWindow *)sheet
returnCode:(NSInteger)returnCode
contextInfo:(void *)contextInfo {
[sheet orderOut:nil];
}
@end
在此示例中,您单击“显示工作表”按钮,工作表开始显示为附加到主窗口。在工作表中,有一个“取消”和一个“确定”按钮,它们都调用了各自的方法。在这些方法中的每一个中,您调用[NSApp endSheet:self.sheet]
. 这告诉NSApp
它应该调用sheetDidEnd:returnCode:contextInfo:
指定为模式委托的对象上的方法。然后在sheetDidEnd:returnCode:contextInfo:
你告诉工作表隐藏自己。
编辑:
每个NSWindow
都有一个“启动时可见”标志,可以在 Interface Builder 中设置。如果设置了此标志,则在加载 nib 文件时窗口将可见。如果未设置,则窗口将隐藏,直到您以编程方式显示它。只需编辑 nib 文件中的标志,如下所示: