7

这似乎应该很容易,但我必须遗漏一些东西。我有一个基于文档的应用程序。我还构建了一个新的 XIB,它有一个 NSTableView 和三个按钮,我打算显示以前文件的列表。我希望在应用程序首次启动时显示此 XIB 而不是文档窗口。一旦用户选择了一个旧文件或点击“新建”按钮,我希望然后转到文档窗口。这是很常见的,我经常看到使用。

在我试图让这个工作的过程中,我修改了 project-info.plist 文件并将主 NIB 文件基本名称从 MyDocument 更改为我的选择 XIB 名称。这会导致应用程序显示选择窗口而不是 MyDocument 窗口。到目前为止,似乎没有任何问题。

在我的选择窗口中,我为这个 XIB 设置了我的表格视图和一个数组控制器和一个自定义窗口控制器。我已将文件的所有者设置为新的窗口控制器,并将窗口控制器的窗口属性绑定到窗口,将窗口的委托属性绑定到文件的所有者以及“选择”、“取消”和“新建”按钮。没有任何东西与 NSApplication 绑定。但奇怪的是,当我运行这个应用程序时,它似乎想将这些控制器连接到 NSApplication 并出现错误(其他两个按钮相同):

无法将动作 selectButton: 连接到 NSApplication 类的目标

它还显示一个错误,即 NSApplication 对于持有对我的数组的引用的插座不符合键值对。Array Controller、Window 和按钮没有绑定到 NSApplication,而是绑定到新的 Window Controller。我本来希望如果有任何问题不会提到 NSApplication 而是控制器绑定到的窗口控制器。

有人知道这里发生了什么吗?这是一个目标操作问题,因为我将“主 NIB 文件基本名称”从“主菜单”更改为“选择”吗?如果我不应该更改它,那么如何让 Cocoa 允许我在显示文档窗口之前显示一个选择屏幕?

任何帮助是极大的赞赏。抢

4

1 回答 1

9

在 IB 中对 nib 的 File's Owner 类的设置只是建议性的;它让 IB 只显示该类的实例提供的出口和操作。它不强制文件的所有者将是该类的实例,因为文件的所有者不是 nib 的一部分。

File's Owner 是加载 nib 的对象。这必然意味着它在笔尖之外,而笔尖中的任何东西都不能决定它的任何东西。在 MainMenu nib 的情况下,它的 File's Owner(加载 MainMenu nib 的对象)是 NSApplication 实例。因此,您在 MainMenu nib 中连接到文件所有者的所有内容,都连接到应用程序对象,即使您告诉 IB 它不是应用程序。

应用程序是 MainMenu nib 的所有者——不管你告诉 IB 什么——不是错误。应用程序始终是 MainMenu nib 的所有者。这是正常和正确的;你不能改变它,不应该试图改变它,也不需要改变它。

简而言之,错误在于您将一个笔尖用于两个截然不同的目的。

您应该让 MainMenu nib 单独存在 - 仅包含 MainMenu、您的自定义文档控制器(我稍后会谈到)和您的应用程序委托 - 并将以前的文档窗口移动到一个单独的 nib 中,由以前的文档窗口控制器。为了让窗口控制器成为这个 nib 的所有者,您需要让窗口控制器加载它。您必须在代码中执行此操作——您无法在 IB 或 plist 中进行设置。

在应用程序的委托中,实例化并拥有窗口控制器。听起来您创建了一个自定义的 NSWindowController 子类,因此您可以覆盖它init以让它自己发送initWithWindowNibName:消息以加载并拥有 nib。然后,只需使用allocinit从应用程序委托创建窗口控制器。

这将消除控制台消息,并确保按钮实际上连接到窗口控制器(因为它们连接到文件所有者,通过此更改,它将成为窗口控制器)。

让您的应用程序委托applicationOpenUntitledFile:通过向窗口控制器发送showWindow:消息来响应。这将使以前的文档窗口出现在用户通常创建新文档的任何时候。

如果您想支持创建文档的常用方法(即允许 New Document 工作),请实现applicationDidFinishLaunching:and applicationShouldHandleReopen:hasVisibleWindows:,而不是applicationOpenUntitledFile:. 确保没有打开任何文档,如果是这种情况,请显示您的窗口。

您还应该创建一个 NSDocumentController 的自定义子类,并使您的文档控制器成为它的一个实例,并在该类中实现addDocument:removeDocument:在最后一个打开的文档关闭时重新显示上一个文档窗口,并在文档打开时隐藏它打开。

于 2010-10-11T04:51:27.883 回答