cocoa - 界面生成器中的 NSWindowController 对象链接

标签 cocoa binding interface-builder nswindowcontroller nsviewcontroller

我创建了一个 NSWindow xib 文件,我想通过单击另一个窗口中的按钮来打开该文件。

现在,为了控制 NSWindow 的行为,我从 xib 中的库中拖动了一个对象,并将其更改为我在 XCode 中定义的 NSWindowController(即 ListingWindowController)的子类。

类似地,我还创建了 NSViewController 的子类(即 ListingViewController)来管理 NSWindow 内的 NSView。为此,我将 NSViewController 从 xib 的 Library 中拖出,并将其类更改为 ListingViewController。

@class ListingViewController;

@interface ListingWindowController : NSWindowController {
    IBOutlet ListingViewController *listingVC;
}

@property (nonatomic, retain) IBOutlet ListingViewController *listingVC;
@end

我在IB中连接了窗口和我的窗口 Controller 的listingVC。

现在,要在启动(第一个)窗口中单击按钮来调用此窗口,我使用 initWithWindowNibName 创建窗口 Controller ,如下所示。

- (IBAction) pushConnect:(id)sender {
    NSLog(@"Connect pushed.");
    if (wc == nil) {
        wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeWindow:) name:NSWindowWillCloseNotification object:nil];

        [wc showWindow:sender];
    }
}

问题是,尽管在 IB 中为即将到来的窗口/ View 的 View Controller 完成了所有绑定(bind),但即使新窗口已加载(下面的代码)。

- (void)windowDidLoad {
    [super windowDidLoad];

NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}

请帮忙解释为什么连接不起作用。我已经为这个问题绞尽脑汁有一段时间了。

PS:我有 iOS 编程背景。因此,我假设 Mac 的窗口/ View Controller 的行为与 iOS UIViewController 类似。

TIA..

最佳答案

请注意:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

意味着self(从你的问题中不清楚self是什么)是ListingWindow.nib的所有者。这意味着 self 是保留该 nib 文件中对象的导出的人,而 self 负责释放 nib 文件中的顶级对象。这也意味着您将在代码中创建 ListingWindowController 实例,并在 nib 文件中创建另一个实例,因为您已拖动 ListingWindowController< 类的对象 到 nib 文件上。

事情不应该是这样的。

在绝大多数情况下,窗口( View ) Controller 加载 nib 文件并成为其所有者。它有一个 window (view) 导出,必须链接到 nib 文件中的顶级窗口( View )。作为 nib 文件的所有者,它必须在加载 nib 文件之前创建。

为了为您的窗口 Controller 实现此目的,您需要将文件的所有者类设置为 ListingWindowController。您不得拖动对象立方体并在 nib 文件内实例化窗口 Controller 。窗口 Controller 是nib文件的所有者,因此它必须在nib文件加载之前存在。您还必须将文件所有者中的 window 导出链接到 nib 文件中的顶级窗口对象,以便窗口 Controller 知道它应该管理哪个窗口。

完成后,使用:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow"];

而不是:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

因为 wc 应该是 nib 文件的所有者。

View Controller 的工作原理类似。它们是在加载 nib 文件之前创建的,负责加载包含 View 作为顶级对象的 nib 文件,是该 nib 文件的所有者,并且具有必须链接的 view 导出到该顶级 View 。

从你的问题中不清楚你是否有一个单独的 nib 文件用于 View 。如果不这样做,那么根本不需要使用 NSViewController 的子类 - 您可以使用 NSObject 的子类来代替。如果您坚持使用 NSViewController 来管理不是从单独的 nib 文件加载的 View ,那么您应该重写 -loadView ,以便某些人获得对该 View 的引用意味着除了从 nib 文件加载它并发送 -setView: 以便它知道它应该管理的 View 之外。

推荐阅读:Nib Files in the Resource Programming Guide , NSWindowController class reference , NSViewController class reference .

关于cocoa - 界面生成器中的 NSWindowController 对象链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6170345/

相关文章:

objective-c - 在其他 View 中调用时,使用 Interface Builder 创建的自定义 View 不会呈现

xcode - 在 NSViewController 之间切换

macos - 以编程方式启动 OS X 的联系人应用程序以显示联系人?

macos - 更新 NSView 全屏背景颜色

binding - 你如何进行语言绑定(bind)?

c# - 如何绑定(bind)到没有名称或 x :Name? 的控件

cocoa - 允许 bundle /插件添加到 Cocoa 应用程序支持的文档扩展中吗?

c# - 为什么从 UI 中删除命令源后调用 CanExecute?

ios - 如何在 XIB 中调整 super View 's height base on subview' 的大小?

cocoa - 界面生成器 : determine which element has the initial focus