2

我创建了一个 NSWindow xib 文件,我想在单击另一个窗口中的按钮时打开它。

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

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

@class ListingViewController;

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

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

我在IB中连接了我的窗口控制器的窗口和listingVC。

现在要在我的启动(第一个)窗口中单击按钮来调用此窗口,我使用 initWithWindowNibName 像这样创建窗口控制器。

- (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 中为即将到来的窗口/视图的视图控制器完成了所有绑定,但即使在新窗口加载后(下面的代码),窗口和 ListingVC 仍然是(null),(null)。

- (void)windowDidLoad {
    [super windowDidLoad];

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

请帮助为什么连接不起作用。我正在努力解决这个问题很长一段时间。

PS:我来自iOS编程背景。所以,我假设 Mac 的窗口/视图控制器的行为类似于 iOS UIViewControllers。

蒂亚..

4

1 回答 1

11

注意:

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

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

这不是它应该的样子。

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

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

完成后,使用:

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

代替:

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

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

视图控制器的工作方式类似。它们在加载 nib 文件之前创建,负责加载包含视图作为顶级对象的 nib 文件,是该 nib 文件的所有者,并且具有view必须链接到该顶级视图的出口。

从您的问题中不清楚您是否有单独的 nib 文件用于视图。如果你不这样做,那么NSViewController根本不需要使用的子类——你可以使用子类来NSObject代替。如果您坚持使用NSViewController来管理未从单独的 nib 文件加载的视图,那么您应该重写-loadView以便通过某种方式获得对视图的引用,而不是从 nib 文件加载它并发送它-setView:以便它是意识到它应该管理的视图。

推荐阅读:资源编程指南中的 Nib 文件NSWindowController 类参考NSViewController 类参考

于 2011-05-29T22:36:04.300 回答