NSViewController 未创建

发布于 2025-01-03 02:36:20 字数 538 浏览 5 评论 0原文

我正在构建一个可可应用程序,其中包含一个带有 xib 的主窗口控制器。该 xib 包含许多自定义视图类。我想向 xib 添加一个 NSViewController,但我遇到了一些麻烦。

在界面生成器中,我可以将 NSViewController 拖到 xib 中,为其分配自定义控制器类,并将其视图分配给 xib 中的相应视图。问题是:initWithNibName:Bundle:loadView 都没有被调用。

我缺少什么?

编辑: 人们似乎误解了这个问题,所以我会澄清一下。

该窗口已经有一个视图控制器。我想要做的是将单独的视图控制器分配给几个子视图。我需要知道如何将我的 NSViewController 子类与适当的 NSView 子类(它是主窗口的子类)关联起来。

或者换句话说,我尝试使用多个 NSViewController 子类来控制单个 .xib 文件中的许多不同的自定义视图(每个视图一个)。这些控制器和子视图有自己的 .xib 文件,它们最终应该在同一窗口中可见。

I am building a cocoa application with one main window controller with a xib. That xib contains many custom view classes. I would like to add an NSViewController to the xib, but i'm running into some trouble.

In interface builder I can drag the NSViewController into the xib, assign it its custom controller class, and assign its view to the appropriate view in the xib. Here's the problem: neither the initWithNibName:Bundle: or loadView get called.

What am I missing?

EDIT:
People seem to be misunderstanding the question so I'll clarify.

The window already has a view controller. What I am seeking to do is assign separate view controllers to several of the subviews. I need to know how to associate my NSViewController subclass with the appropriate NSView subclass (which is a child of the main window).

Or in other words, I am trying to use multiple NSViewController subclasses to controll many different custom views (one each) within a single .xib file. Those controllers and subviews have their own .xibs which should ultimately become visible in the same window.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤芳又自赏 2025-01-10 02:36:20

我用于 NSViewController 的模式是每个视图控制器都有一个 xib。然后,当您需要该视图控制器时,您可以分配它并使用initWithNibName:Bundle:方法。一旦您使用它的视图,loadView就会被调用。

例子:

self.editViewController = [[[MyEditViewController alloc] initWithNibName:@"MyEditViewController" bundle: nil] autorelease];
[self.window setContentView: editViewController.view];

The pattern I use for NSViewController is to have a xib per view controller. Then, when you need that view controller you alloc it and use the initWithNibName:Bundle: method. As soon as you use its view, loadView will get called.

Example:

self.editViewController = [[[MyEditViewController alloc] initWithNibName:@"MyEditViewController" bundle: nil] autorelease];
[self.window setContentView: editViewController.view];
屋顶上的小猫咪 2025-01-10 02:36:20

我曾经也被这个问题困扰并放弃了那个东西——IB调色板中带有白色边框视图的蓝色圆圈。我现在从代码创建控制器,并且仅通过文件所有者在 IB 中设置对所属控制器类的引用:右键单击文件所有者,在身份检查器中输入类名,然后从文件所有者视图到看法。

然后,在您的代码中,您可以在适当的初始化点执行操作:

[self setMyViewController = [[MyViewController alloc] initWithNibName: @"MyView" bundle: [NSBundle mainBundle]]

对于您的特定情况,当您的窗口从其笔尖加载并准备好工作时,这可能是在 windowDidLoad 方法中。然后,您可以将该视图添加到 Windows 内容视图中。此外,您可能需要考虑在视图和视图控制器之间建立 1:1 的关系。在维护方面,它使生活变得更加容易。

编辑:就像@pcperini 在他的评论中建议的那样,您可以使用调色板组件,但您仍然需要在代码中实例化控制器。如果您想使用调色板组件,请在主控制器或 AppDelegate 中创建一个属性:

@property (...) MyViewController *myViewController;

添加代码行以实际创建控制器(见上文)。然后,使用绑定检查器将调色板组件绑定到 myViewController 属性。

因此,您缺少的是实际上没有实例化控制器对象。

编辑2:这是代码(awakeFromNib是顶部控制器的方法)。它创建两个子控制器,每个子控制器处理不同的子视图:

- (void) awakeFromNib {

    [[self startEndTopicHeader] setHeader: @"Event timeline boundary"];
    [[self startDateHeaderView] setHeader: @"Event (start) date"];
    [[self endDateHeaderView] setHeader: @"Event end date"];

    [self setStartDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self startDateViewController] view] setFrame: [[self dummyStartView] bounds]];
    [[self dummyStartView] addSubview: [[self startDateViewController] view]];
    [[self startDateViewController] setParentController: self];

    [self setEndDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self endDateViewController] view] setFrame: [[self dummyEndView] bounds]];
    [[self dummyEndView] addSubview: [[self endDateViewController] view]];
    [[self endDateViewController] setParentController: self];

}

I used to get stuck with that as well and gave up on that thing - the blue circle with a white bordered view in it from the IB palette. I now create my controllers from code and only set a reference in IB to the owning controller class via the file owner: right click the file owner, enter the class name in the Identity inspector and then make a connection from the file's owner view to the view.

In your code you then do at an appropriate initialisation point:

[self setMyViewController = [[MyViewController alloc] initWithNibName: @"MyView" bundle: [NSBundle mainBundle]]

For your specific case this could be in windowDidLoad method when your window is loaded from its nib and ready for work. You can then add the view to your windows content view. Also you might want to consider to have a 1:1 relation between view and view controller. It makes life a lot easier in terms of maintenance.

EDIT: Like @pcperini suggests in his comments you can use the palette component, but you'll still need to instantiate the controller in your code. If you want to use the palette component, create a property in your main controller or AppDelegate:

@property (...) MyViewController *myViewController;

Add the line of code to actually create the controller (see above). Then, using the bindings inspector bind the palette component to the myViewController property.

So, what you are missing is that you are actually not instantiating the controller object.

EDIT 2: Here's the code (the awakeFromNib is the method of the top controller). It creates two child controllers each handling a different subview:

- (void) awakeFromNib {

    [[self startEndTopicHeader] setHeader: @"Event timeline boundary"];
    [[self startDateHeaderView] setHeader: @"Event (start) date"];
    [[self endDateHeaderView] setHeader: @"Event end date"];

    [self setStartDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self startDateViewController] view] setFrame: [[self dummyStartView] bounds]];
    [[self dummyStartView] addSubview: [[self startDateViewController] view]];
    [[self startDateViewController] setParentController: self];

    [self setEndDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
    [[[self endDateViewController] view] setFrame: [[self dummyEndView] bounds]];
    [[self dummyEndView] addSubview: [[self endDateViewController] view]];
    [[self endDateViewController] setParentController: self];

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文