Macos 界面生成器:";“合并”;NSView类与.xib

Macos 界面生成器:";“合并”;NSView类与.xib,macos,interface-builder,Macos,Interface Builder,我想在Interface Builder中设置一个自定义NSView,但我无法让它在OSX中工作 在我的ViewController的.xib中,我添加了一个自定义视图,并将该类设置为MyCustomView。我创建了MyCustomView.h、MyCustomView.m和MyCustomView.xib 在MyCustomView.xib中,我还将类设置为MyCustomView。在MyCustomView.m中,调用了从nib调用的-(void)awakeFromNib,但是-(id)i

我想在Interface Builder中设置一个自定义NSView,但我无法让它在OSX中工作

在我的ViewController的.xib中,我添加了一个自定义视图,并将该类设置为MyCustomView。我创建了MyCustomView.h、MyCustomView.m和MyCustomView.xib

在MyCustomView.xib中,我还将类设置为MyCustomView。在MyCustomView.m中,调用了从nib调用的
-(void)awakeFromNib
,但是
-(id)initWithCoder:(NSCoder*)aDecoder
-(id)awakefausingcoder:(NSCoder*)aDecoder
没有调用

我想要实现的是,在我的ViewController中,我添加的视图被我在MyCustomView.xib中设置的视图“填充”。最好的方法是什么

编辑:我觉得我不够清楚…

我的ViewController包含一个名为MyCustomView的自定义视图

此视图应为MyCustomView类型,其中

MyCustomView.h MyCustomView.m MyCustomView.xib

存在。我已经将MyCustomView.xib文件的所有者设置为MyCustomView,并且我已经将ViewController中的CustomView设置为MyCustomView,但它不起作用

如果我和你一起做

- (void)awakeFromNib {
    NSString* nibName = NSStringFromClass([self class]);
    NSArray* topLevelObjects;
    [[NSBundle mainBundle] loadNibNamed:nibName
                              owner:nil
                    topLevelObjects:&topLevelObjects];

    NSView* view = topLevelObjects[0];
    [view setFrame:[self bounds]];
    [self addSubview:view];
}
我只获得NSView类型的视图,而不是MyCustomView。。。没有简单的方法告诉ViewController.xib它是MyCustomView吗

编辑2:我上传了一个简单的项目

此时,您会发现一个带有MyCustomView的简单项目(不是在ViewController中,而是在window.xib中),但它不会显示MyCustomView.xib中的按钮。我想做到这一点-最简单、最好的方法是什么?

编辑-抱歉,我现有的答案没有考虑到连接插座和操作的需要。这样就可以了

考虑到这些文件

MyCustomView.h
MyCustomView.m
MyCustomView.xib
在MyCustomView.h中

  • 为接口元素声明IBOutlet。您至少需要一个,以保持指向xib文件中顶级视图的指针

    @property(非原子,强)ibview*view

在MyCustomView.xib中

  • 确保只有一个顶级视图
  • 在Identity Inspector中将文件的所有者类设置为MyCustomView
  • 确保顶级视图设置为默认的
    NSView
  • 现在,您可以将MyCustomView.h中声明的IBOutlets连接到xib文件中的接口对象。至少您需要将顶层视图连接到
    视图
    插座
在MyCustomView.m中:

- (id)initWithFrame:(NSRect)frame
{
    NSString* nibName = NSStringFromClass([self class]);
    self = [super initWithFrame:frame];
    if (self) {
        if ([[NSBundle mainBundle] loadNibNamed:nibName 
                                          owner:self 
                                topLevelObjects:nil]) {
            [self.view setFrame:[self bounds]];
            [self addSubview:self.view];
            [self.myCustomButton setTitle:@"test success"];
        }
    }
    return self;
}
在窗口的xib文件中,添加自定义NSView并将其类更改为MyCustomView

在10.8之前的OSX中,方法
loadNibNamed
是一个类方法-如果需要向后兼容,请使用它,但现在不推荐使用它:

[NSBundle loadNibNamed:@"NibView" owner:self]
请注意,MyCustomView.xib的视图不是MyCustomView的视图,而是其视图的唯一子视图(这类似于tableViewCell拥有单个contentView的方式)

在发布的项目示例中,您需要进行以下更改:

  • 在MyCustomView.h中
    . 添加NSView属性

  • 在MyCustomView.xib中:
    . 将顶级视图从
    MyCustomView
    自定义类更改为
    NSView
    (默认值)
    . 将文件的所有者设置为
    MyCustomView

    . 将文件所有者的
    视图
    myCustomButton
    中的IBOutlets连接到界面视图和按钮
    . 为了进行测试,请将视图缩小很多,并将按钮按到右上角(您不会在窗口中看到它,因为它就在这里)

  • 在MyCustomView.m中:
    . 在这里用
    initWithFrame
    方法替换所有实现代码


要加载视图或控件的自定义子类(或可在Interface Builder中使用的任何其他类),您需要添加基本版本(本例中为NSView,如您所做),然后在窗口中选择该对象并转到Identity Inspector(Cmd Opt 3)

输入自定义子类的名称,而不是类的预定义值(在您的示例中是NSView)。瞧


与IB UX相关的一个小细节是,您可能必须将焦点从输入字段移开,以便在构建和运行应用程序时注册该更改。

您想实现什么?这是一套标准控件,您需要在许多地方使用吗?是否有视图的各个部分需要触发的操作,或您需要从
ViewController
访问的出口?view类真的更像一个子视图控制器吗?另外,上面列出的
-awakeFromNib
代码(
MyCustomClass
ViewController
)在哪里?请查看我上传的项目,它应该会更清晰。
awakeFromNib
位于
MyCustomClass
中。我已经这样做了,但不起作用,请以我上传的项目为例。现在看起来好多了,但按钮的标题没有设置为“测试成功”;这对你有效吗?@swalkner,我(再次)测试了你的项目,它有效。您是否将文件所有者中的view和myCustomButton都重新连接到Xib按钮?它可以工作,非常感谢-我让它连接到自定义视图,而不是文件所有者。现在我正在解决一个类似的问题(在IB中添加ViewController的视图),但我想这是一个新问题。。。谢谢@铸造厂我会认为,像上面这样的事情会更简单,因为它需要做得更频繁?如上所述,这几乎让人觉得你是在违背计划去完成它。可可中使用了哪些其他模式来实现类似的结果?