我需要一个视图,其中包含滑块和按钮等控件,并具有彩色背景。我不确定是继承 NSView 还是 NSViewController。我想我可以继承一个 NSView 并绘制一个自定义背景并在 xib 中布局控件,并将出口设置为 NSView 子类。
如果要使用 xib,则必须使用 NSViewController 子类;这就是它的用途。
一般来说,对于您要执行的操作(将多个控件捆绑在一起),NSViewController 是要使用的类。
你也可以从模型-视图-控制器模式的角度来看这一点(即视图控制器和视图的来源):视图与事物的外观有关;控制器与用户交互(以及与模型的交互)有关。
你当然可以定义一个NSView 子类并定义它的内容,无论是编程方式还是在 IB 中(将滑块和按钮作为子视图添加到它),但我认为它没有多大优势,除非你要去提供一种特定的控制。
编辑:
您在评论中声明您希望在NSSplitView 中使用您自定义的、IB 定义的NSView。这让事情变得更加情境化。
现在,像往常一样,有许多设计选项,例如,您可以定义自己的 MySplitController 允许您指定应该从中加载拆分视图的子视图的 nib。
但是,如果我正确理解您的目标,您想做的是在 xib 中定义一个 NSView 并在 NSSplitView 中使用它,就像它是 IB 允许的默认视图类型之一一样。
Interface Builder Plug-ins 允许这样做。不幸的是,Xcode 4 似乎不再支持它们。
然后我看到的唯一选择是定义NSView 的子类,例如MyCustomView,然后在其initWithFrame: 方法中加载xib 文件,识别您在其中定义的视图,并将其添加为子视图。
具体来说,您可以使用此代码加载 xib 文件顶级对象,其中将找到您的自定义视图:
NSNib *nib = [[[NSNib alloc] initWithNibNamed:@"MyView" bundle:nil] autorelease];
NSArray *topLevelObjects;
if (![nib instantiateWithOwner:customViewOwner topLevelObjects:&topLevelObjects]) {
//- handle error
}
MyView *myView = nil;
for (id topLevelObject in topLevelObjects) {
if ([topLevelObject isKindOfClass:[MyView class]) {
myView = topLevelObject;
break;
}
}
为了简化事情,您可以让这个 xib 文件只定义您的自定义 NSView 和普遍存在的文件所有者(这是将视图集成到应用程序其余部分的链接)。
如您所见,我将customViewOwner 传递给instantiateWithOwner:这将是您的主视图控制器或应用程序委托,负责响应来自自定义视图的所有操作并在需要时设置其状态。此类将是您的 xib 的文件所有者,因此要进行真正的模块化设计,最好定义您在特定项目中子类化的 MyCustomViewController。
一旦你定义了这样一个自定义的 NSView 子类,那么你唯一需要做的就是将它集成到你的 NSSplitView 中,将 NSSplitView 的子视图类设置为MyCustomView。
这不像使用 IB 插件那么简单,但它可以很好地实现集成在不同 xib 文件中定义的视图的目的。