【问题标题】:Subclass NSViewController or NSView子类 NSViewController 或 NSView
【发布时间】:2012-10-30 17:39:33
【问题描述】:

我需要一个视图,其中包含滑块和按钮等控件,并具有彩色背景。我不确定是继承NSView 还是NSViewController。我想我可以继承 NSView 并绘制自定义背景并在 xib 中布局控件,并将出口设置为 NSView 子类。

一些按钮需要切换,例如播放/暂停按钮,我认为这个逻辑应该在NSView 中完成,并且在按钮切换时通知NSViewController,而不是NSViewController 必须管理自行切换。

但是当我去创建NSView 子类时,创建xib 的选项是灰色的,只有NSViewController 才有可能。那么我必须在NSViewController 上拥有网点吗?

我想要myView.playPauseButton,但似乎我必须拥有myViewController.playPauseButton?

【问题讨论】:

    标签: objective-c macos appkit


    【解决方案1】:

    我需要一个视图,其中包含滑块和按钮等控件,并具有彩色背景。我不确定是继承 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 文件中定义的视图的目的。

    【讨论】:

    • 所以我继承了 NSViewController,在 Interface builder 中添加了我的控件(在主窗口的 xib 的单独 nib 中),我如何将视图控制器的视图添加到主 nib 的窗口中?
    • 在您的应用委托中,实例化您的自定义视图控制器(并将其存储到一个强属性中),然后将myController.view 作为子视图添加到窗口中(addSubview:)。
    • 对不起,对我来说,代码要容易得多,但可以在 IB 中完成:将控制器添加到您的 xib 文件并将其类设置为您的自定义类;在您的应用程序委托中创建一个插座并将插座绑定到视图控制器;此外,将 window.view 绑定到 controller.view 就完成了。
    • 但是 controller.view 会绑定到我创建子类时创建的另一个 xib 中的视图?
    • 是的,这是视图控制器内部的一部分;您只告诉 UIWindow 使用控制器的视图...控制器将从 xib 加载其视图...
    【解决方案2】:

    最好将 NSViewController 子类化并使用 xib 初始化或在代码中手动布局子视图。根据我的经验,子类化 NSView 从来没有达到我想要的方式,包括您正在寻找的实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      相关资源
      最近更新 更多