界面生成器中的 NSWindowController 对象链接
我创建了一个 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中连接了窗口和我的窗口控制器的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 中为即将到来的窗口的视图控制器完成了所有绑定/view,即使在新窗口加载后(下面的代码),窗口和listingVC也会显示为(null),(null)。
- (void)windowDidLoad {
[super windowDidLoad];
NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}
请帮助解释为什么连接不起作用。我已经为这个问题绞尽脑汁有一段时间了。
PS:我有iOS编程背景。因此,我假设 Mac 的窗口/视图控制器的行为与 iOS UIViewController 类似。
蒂亚..
I created a NSWindow xib file that I want to open on click of a button in another window.
Now, to control the behavior of the NSWindow, I dragged an object from Library in xib and changed it to subclass of NSWindowController (i.e. ListingWindowController) that I defined in XCode.
Similarly I also created a subclass of NSViewController (i.e. ListingViewController) to manage the NSView inside the NSWindow. To do this, I dragged NSViewController from Library in xib and changed its class to ListingViewController.
@class ListingViewController;
@interface ListingWindowController : NSWindowController {
IBOutlet ListingViewController *listingVC;
}
@property (nonatomic, retain) IBOutlet ListingViewController *listingVC;
@end
I connected window and listingVC of my window controller in IB.
Now to invoke this window on click of a button in my launch (first) window, I create the window controller using initWithWindowNibName like this..
- (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];
}
}
The problem is that despite all the bindings done in IB for the view controllers of upcoming window/view, the window and listingVC comes out to be (null), (null) even after the new window has loaded (below code).
- (void)windowDidLoad {
[super windowDidLoad];
NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}
Please help why the connections are not working. I'm banging my head against this problem for quite a while now.
PS: I'm coming from iOS programming background. So, I'm assuming the Mac's window/view controller behave similar to iOS UIViewControllers.
TIA..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请注意:
意味着
self
(从你的问题中不清楚self
是什么)是ListingWindow.nib
的所有者。这意味着 self 是保留该 nib 文件中对象的出口的人,而 self 负责释放 nib 文件中的顶级对象。这也意味着您将在代码中创建ListingWindowController
实例,并在 nib 文件中创建另一个实例,因为您已拖动ListingWindowController< 类的对象/code> 到 nib 文件上。
这不应该是这样的。
在绝大多数情况下,窗口(视图)控制器加载 nib 文件并成为其所有者。它有一个
window
(view
) 出口,必须链接到 nib 文件中的顶级窗口(视图)。作为 nib 文件的所有者,它必须在加载 nib 文件之前创建。为了为您的窗口控制器实现此目的,您需要将文件的所有者类设置为
ListingWindowController
。您不得拖动对象立方体并在 nib 文件内实例化窗口控制器。窗口控制器是nib文件的所有者,因此它必须在nib文件加载之前存在。您还必须将文件所有者中的window
出口链接到 nib 文件中的顶级窗口对象,以便窗口控制器知道它应该管理哪个窗口。完成此操作后,请使用:
而不是:,
因为
wc
应该是 nib 文件的所有者。视图控制器的工作原理类似。它们是在加载 nib 文件之前创建的,负责加载包含视图作为顶级对象的 nib 文件,是该 nib 文件的所有者,并且具有必须链接的
view
出口到那个顶层视图。从您的问题中不清楚您是否有一个单独的 nib 文件用于视图。如果不这样做,那么根本不需要使用
NSViewController
的子类 - 您可以使用NSObject
的子类来代替。如果您坚持使用 NSViewController 来管理不是从单独的 nib 文件加载的视图,那么您应该重写 -loadView ,以便某些人获得对该视图的引用意味着除了从 nib 文件加载它并发送-setView:
以便它知道它应该管理的视图之外。推荐阅读:资源编程指南中的 Nib 文件, NSWindowController类参考,NSViewController 类参考。
Note that:
means that
self
(it’s not clear whatself
is from your question) is the owner ofListingWindow.nib
. This means thatself
is the one who keeps outlets to objects in that nib file, andself
is responsible for releasing the top-level objects in the nib file. This also means that you’re creating an instance ofListingWindowController
in your code and another instance inside your nib file since you’ve dragged an object of classListingWindowController
onto the nib file.This is not how it’s supposed to be.
In the vast majority of cases, a window (view) controller loads a nib file and becomes its owner. It has a
window
(view
) outlet that must be linked to a top-level window (view) in the nib file. Being the nib file’s owner, it must have been created before the nib file is loaded.In order to achieve this for your window controller, you need to set the file’s owner class to
ListingWindowController
. You must not drag an object cube and instantiate the window controller inside the nib file. The window controller is the owner of the nib file, so it must exist before the nib file is loaded. You must also link thewindow
outlet in file’s owner to the top-level window object in the nib file so that the window controller is aware of what window it should manage.Having done that, use:
instead of:
since
wc
is supposed to be the owner of the nib file.View controllers work similarly. They’re created before loading the nib file, are responsible for loading a nib file that contains a view as a top-level object, are that nib file’s owner, and have a
view
outlet that must be linked to that top-level view.It’s not clear from your question whether you have a separate nib file for the view. If you don’t, then using a subclass of
NSViewController
is not needed at all — you could use a subclass ofNSObject
instead. If you insist on usingNSViewController
to manage a view that’s not loaded from a separate nib file, then you should override-loadView
so that you get a reference to the view by some means other than loading it from a nib file, and sending it-setView:
so that it is aware of the view it’s supposed to be managing.Recommended reading: Nib Files in the Resource Programming Guide, NSWindowController class reference, NSViewController class reference.