【问题标题】:Showing a non-modal template chooser synchronously同步显示非模态模板选择器
【发布时间】:2012-02-20 02:59:15
【问题描述】:

我正在使用文档架构编写一个 Cocoa 应用程序。每当在此应用程序中创建无标题文档时,应向用户显示一个窗口,让他们选择模板并提示输入其他信息。一次只能显示这些窗口中的一个,并且最好在模板选择器可见时与应用程序的其余部分进行交互。 (这就是 Pages 的行为方式。)

通过覆盖-[NSDocumentController openUntitledDocumentAndDisplay:error:],我已经完成了大部分工作:

- (id)openUntitledDocumentAndDisplay:(BOOL)displayDocument 
                               error:(NSError *__autoreleasing *)outError {
    TsDocument * doc = [self makeUntitledDocumentOfType:self.defaultType 
                                                  error:outError];
    if(!doc) {
        return nil;
    }

    TsNewWindowController * newController = [TsNewWindowController new];
    newController.document = doc;

    if([NSApp runModalForWindow:newController.window] == NSRunAbortedResponse) {
        if(outError) {
            *outError = [NSError errorWithDomain:NSCocoaErrorDomain 
                                            code:NSUserCancelledError 
                                       userInfo:nil];
        }
        return nil;
    }

    [self addDocument:doc];

    if(displayDocument) {
        [doc makeWindowControllers];
        [doc showWindows];
    }

    return doc;
}

但是,如您所见,窗口以模态方式显示,阻止访问应用程序的其余部分。有没有一种简单的方法来实现我想要的而不使模板选择器模式化?


为了更清楚地解释几件事:

  1. 我当然知道-runModalForWindow: 会以模态方式运行窗口——它就在名称中!我正在寻找另一种方法来显示仍会阻止-openUntitledDocumentAndDisplay:error: 的窗口,或者根本不需要我阻止该方法。

  2. 我不相信我可以简单地创建文档,显示newController 的窗口,然后调用文档的makeWindowControllersshowWindows,因为如果应用退出,恢复将不会显示模板选择器——它显示了正常的编辑界面。

【问题讨论】:

    标签: cocoa nsdocument


    【解决方案1】:

    您确实需要创建和使用NSWindowController,但您需要在调用openUntitledDocument…:: 之前这样做。

    在未发布的 Adium Xtras Creator 中,我在几个方面进行了挖掘:

    • 在应用程序的委托中,在applicationOpenUntitledFile: 中,我显示模板选择器窗口并返回YES
    • 在文档控制器中,在removeDocument: 中,我将消息传递给super,然后检查是否还有打开的文档。如果没有,我会显示模板选择器窗口。
    • 在文档控制器中,在addDocument: 中,我隐藏了模板选择器窗口,然后传递给super

    因此:

    • 如果用户尝试以任何方式创建新文档(没有特定类型),则会显示模板选择器。
    • 如果用户以任何方式创建新文档(显式类型),模板选择器将被隐藏。 (我在其中执行此操作的应用程序将其“新建”菜单项设置为包含特定类型的子菜单。)
    • 如果用户以任何方式打开任何文档,模板选择器将被隐藏。
    • 如果用户关闭最后打开的文档,将显示模板选择器。
    • 如果用户或其他应用程序尝试以任何方式重新打开应用程序,则会显示模板选择器。

    【讨论】:

      【解决方案2】:

      您正在调用runModalForWindow:,所以它当然将窗口作为模式窗口运行。

      为什么不直接显示窗口呢?使用NSWindowController 并调用showWindow: 以显示模板窗口。在您的窗口控制器中,实现对用户选择做出反应的操作,然后创建相应的文档(或取消)。

      我认为您实际上不需要在 openUntitledDocumentAndDisplay:error: 中创建文档。

      【讨论】:

      • 当然,我确实意识到-runModalForWindow: 将以模态方式运行窗口——我已经扩展了原始帖子以更详细地回答这一点。我真的可以从-openUntitledDocumentAndDisplay:error: 返回而不返回打开的文档吗?如果我这样做,我的调用者不会尝试显示错误吗?
      • 当你尝试时会发生什么?
      • openUntitledDocumentAndDisplay:error:返回nil会导致抛出异常; niloutError遗憾地没有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      • 2015-04-04
      • 2019-06-02
      相关资源
      最近更新 更多