Cocoa 如何从代码中加载nib文件?

Cocoa 如何从代码中加载nib文件?,cocoa,nsview,Cocoa,Nsview,我在interface builder中创建了一个带有几个按钮的自定义视图。我在代码中为它创建了一个类作为“文件所有者”,将按钮连接到动作方法 那我该如何使用这门课呢 我不能就这样做 StartScreen *ss = [[StartScreen alloc] initWithFrame: ...]; [self.window.contentView addSubView: ss]; ... @implementation StartScreen - (id) init { if ((

我在interface builder中创建了一个带有几个按钮的自定义视图。我在代码中为它创建了一个类作为“文件所有者”,将按钮连接到动作方法

那我该如何使用这门课呢

我不能就这样做

StartScreen *ss = [[StartScreen alloc] initWithFrame: ...];
[self.window.contentView addSubView: ss];
...
@implementation StartScreen
- (id) init {
    if ((self = [super init])) {
        if (![NSBundle loadNibNamed:@"StartScreen" owner:self])
            // error
        // continue initializing
    }
    return self;
}
因为这只会生成一个空视图。(当然:StartScreen类还不知道关于nib文件的任何信息。)

我想做的是:

StartScreen *ss = LoadCustomViewFromNib(@"StartScreen");
[self.window.contentView addSubView: ss];
或者我不得不说

[self iWannaBeANibWithName: @"StartScreen"];
在StartScreen的构造函数中

请帮忙。。。
(顺便说一句,我是为Mac OS X 10.6开发的)

Nib加载函数是
NSBundle
类的一部分。你可以这样使用它

StartScreen *ss = [[StartScreen alloc] initWithFrame: ...];
[self.window.contentView addSubView: ss];
...
@implementation StartScreen
- (id) init {
    if ((self = [super init])) {
        if (![NSBundle loadNibNamed:@"StartScreen" owner:self])
            // error
        // continue initializing
    }
    return self;
}

请参阅。

一个选项是将
StartScreen
作为
NSViewController
的子类,可能将其名称更改为
StartScreenController
。如果您的nib文件中有
IBActions
,并且/或者您希望将视图控制代码放在自己的类中,那么这可能是一个更模块化的解决方案

  • StartScreenController
    声明为
    NSViewController
  • 如果需要,在
    StartScreenController
    中声明
    IBOutlets
  • 将nib文件的所有者类设置为
    StartScreenController
  • 将文件的所有者
    view
    outlet连接到视图对象,并根据需要连接其他outlet
  • 然后:


    如果你没有使用垃圾收集,别忘了在不再需要时发布
    ss

    你有没有看过我不是为iPhone开发的。它应该也适用于Mac,就像Dietrich发布的那样。它对我还不起作用,但我想我发现了问题所在。我已经使StartScreen类成为NSView的一个子类。但我认为它应该是NSObject的一个子类,对吗?但是我如何显示这个视图呢?我的意思是,我不能在app委托中调用[self.window.contentView addSubView],因为我没有看到视图对象,是吗?(我怀疑它不应该是NSView的子类,因为您使用-init作为构造函数,而不是-initWithFrame:)我现在调用-initWithFrame:构造函数中的loadNibNamed:方法。我验证了它是否被调用,甚至调用了drawRect:方法,但我在屏幕上看不到nib文件的内容。为了显示视图,必须将其放在窗口中。我知道:-)但是视图在哪里?我没有像Bavaried指出的那样连接视图插座。但最后,我不喜欢仅仅为了显示一个nib文件而做那么多工作,所以我创建了自己的视图控制器类,它可以正常工作(tm)。只需要70行代码,包括空行和注释,就可以创建一个比NSViewController更好的视图控制器类。使用MyViewController,我不需要指定nib名称,也不需要连接视图出口。这给了我一个错误:
    -[NSViewController loadView]加载了“StartScreen”nib但没有设置视图。
    但我最终解决了问题:我直接初始化并实例化nib,并遍历其顶层对象以找到视图对象。NSNib*nib=[[NSNib alloc]initWithNibNamed:@“StartScreen”bundle:nil];StartScreen*ss=[[StartScreen alloc]init];NSArray*aa;BOOL ok=[nib实例化ENIBWITHOWNER:ss topLevelObjects:&aa];aa包含两个对象,其中一个是我需要的视图对象。@Michael您出现此错误是因为您错过了步骤4:连接
    视图
    插座。谢谢您的帮助!但我认为这比应该的更复杂。我用另一种方式解决了这个问题:我创建了自己的视图控制器类(NSObject的一个子类),它可以自动加载nib。它还将视图连接到实例变量。我只需要做
    StartScreen*ss=[[StartScreen alloc]init]
    [self.window.contentView addSubview:ss.view]在应用程序代理中,一切正常。甚至不需要指定nib名称-init只调用+nibName来获取nib名称,而我的默认实现只返回类名。@Michael您实际上复制了
    NSViewController
    已经为您做的事情,所以我不确定为什么使用
    NSViewController
    会更复杂。不管怎样,只要对你有用!