【问题标题】:How do I dismiss an NSPanel when creating or opening a new document?创建或打开新文档时如何关闭 NSPanel?
【发布时间】:2010-05-13 14:24:44
【问题描述】:

我正在开发一个基于文档的 Cocoa 应用程序。在启动时,用户会看到一个“欢迎面板”(类型为NSPanel),其中包含用于“创建新文档”和“打开现有文档”等常用操作的按钮。这些操作分别与第一响应者的newDocument:openDocument: 操作相关联,就像文件菜单中的匹配项一样。

一切都按预期工作......有三个警告:

  1. 创建或打开新文档时,欢迎面板不会关闭。
  2. 文档窗口在创建时没有焦点。
  3. 打开的文档窗口在窗口标题栏中没有显示打开的文件;同样,新的文档窗口不会像预期的那样使用“Untitled”、“Untitled 2”、“Untitled 3”等标题创建。 (我之所以提到这一点,不仅是因为它很烦人,还因为它可能会帮助您了解问题所在。)

通过将我的应用程序控制器设置为欢迎面板的代表,我已经部分解决了问题 1。单击“打开现有文档”按钮时,面板将退出其键状态(因为正在打开文件浏览器对话框),因此我可以在委托的 windowDidResignKey: 方法中关闭面板。但是,我不知道在创建新文档时如何关闭面板,因为在创建新文档时找不到发布的通知或调用的委托方法。最终,#2 仍然是一个问题,因为文档窗口在创建时没有获得焦点。

我只对NSDocument 进行了子类化——我根本没有使用自定义文档或窗口控制器。我还尝试将面板更改为NSWindow,认为NSWindow 的行为可能不同,但会出现相同的问题。

【问题讨论】:

  • 其他人可能会回答这个问题,但如果您可以创建并发布一个示例应用程序来演示该问题,这将是(并且总是)有用的。
  • 我愿意,但我认为代码本身并不相关。界面的相关部分是一个 nib(所以没有代码),应用程序利用 Cocoa 的文档框架来完成它的工作,所以应用程序本身的代码相对较少。

标签: cocoa nsdocument document-architecture


【解决方案1】:

制作一个自定义文档控制器,让它知道您的起点面板的控制器,然后在addDocument: 中隐藏窗口并在removeDocument: 中再次显示(如果没有其他文档)。

这就是我们在Adium Xtras Creator 中所做的。该代码位于a BSD license 下(与 Adium 本身不同),因此您可以根据需要借用它。

【讨论】:

  • 这解决了第一个问题,但第二个问题——新/打开的文档窗口没有关注创建——仍然存在。有什么想法可能导致该问题吗?
  • 不。 Adium Xtras Creator 没有这个问题。新窗口不是关键,不是主窗口,还是两者都不是?
【解决方案2】:

无需链接到第一响应者的默认操作,只需在您的窗口控制器中创建自定义操作方法并设置您的按钮来触发这些操作。在您的方法中,您需要关闭欢迎窗口,然后创建一个新文档。

类似这样的:

- (IBAction)createNewDocument:(id)sender
{
    //this will close the window if you're using NSWindowController
    [self close];
    [[NSDocumentController sharedDocumentController] newDocument:sender];
}

或者,如果您没有在欢迎窗口中使用 NSWindowController,您可以直接向窗口发送消息:

- (IBAction)createNewDocument:(id)sender
{
    //assume you have a "window" outlet connected to your welcome window
    [window orderOut:sender];
    [[NSDocumentController sharedDocumentController] newDocument:sender];
}

【讨论】:

  • 这行得通,保存项目#2:文档窗口出现时没有焦点。关于如何实现这一点的任何想法?
  • 尝试在下一个事件循环中调用-newDocument方法:[[NSDocumentController sharedDocumentController] performSelector:@selector(newDocument:) withObject:sender afterDelay:0];
  • 在这种情况下,您可能想尝试NSDocumentController-openUntitledDocumentAndDisplay:error: 方法,而不是-newDocument:。它返回一个NSDocument 对象,然后您可以通过其窗口控制器获取该窗口。然后,您可以使用NSWindow-makeKeyAndOrderFront: 方法告诉窗口在前面订购。不过,您需要这样做似乎有点奇怪,通常这应该“正常工作”。
猜你喜欢
  • 2014-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多