NSViewController 没有被创建

Posted

技术标签:

【中文标题】NSViewController 没有被创建【英文标题】:NSViewController not being created 【发布时间】:2012-02-04 22:17:02 【问题描述】:

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

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

我错过了什么?

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

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

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

【问题讨论】:

你从什么引用NSViewController 我将它添加到 xib 文件中(拖放),然后将其类分配给我使用 IB 创建的类。右侧有一个选项卡,可让您设置其“文件所有者”。 对,但是如果你只是将一个对象放在xib 中的任何位置,它不一定会渲染,尤其是像NSViewController 这样的非视图对象。您必须从代码中实例化NSViewController(在这种情况下,您的xib 将保持对它的引用为File's Owner),或者将其设置为ApplicationDelegatewindowrootViewController 我正在使用我的答案中描述的方法在我的应用程序中这样做。一个“***控制器”和几个“子控制器”。我使用我的应用中的示例编辑了我的答案。 【参考方案1】:

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

例子:

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

【讨论】:

这不是我的问题,我正在尝试为子视图创建一个视图控制器。 @mtmurdock 您是否检查过您拖入 xib 的控制器组件实际上是否包含您的控制器实例?【参考方案2】:

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

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

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

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

编辑:就像@pcperini 在他的 cmets 中建议的那样,您可以使用调色板组件,但您仍然需要在代码中实例化控制器。如果要使用调色板组件,请在主控制器或 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];


【讨论】:

以上是关于NSViewController 没有被创建的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式创建 NSTableView 和自定义 NSViewController

NSViewController 和界面生成器

如何在 Mac OS X 应用程序中从一个 NSViewcontroller 推送到另一个 NSViewcontroller?

将 NSViewController 与自定义视图一起使用

ARC 似乎正在释放我的 NSViewController 的视图

Cocoa:NSViewController 视图中的设置器