【问题标题】:How do I load a nib file from Code?如何从 Code 加载 nib 文件?
【发布时间】:2011-08-25 23:48:27
【问题描述】:

我在界面构建器中创建了一个自定义视图,其中包含一些按钮。我在代码中为它创建了一个类作为“文件所有者”,以将按钮连接到操作方法。

那我该如何使用这个类呢?

我不能就这样……

StartScreen *ss = [[StartScreen alloc] initWithFrame: ...];
[self.window.contentView addSubView: ss];
...

因为这只会产生一个空视图。 (当然:StartScreen 类对 nib 文件一无所知。)

我想做的是这样的:

StartScreen *ss = LoadCustomViewFromNib(@"StartScreen");
[self.window.contentView addSubView: ss];

也许我不得不说类似的话

[self iWannaBeANibWithName: @"StartScreen"];

在 StartScreen 的构造函数中?

请帮助... (顺便说一句,我正在为 Mac OS X 10.6 开发)

【问题讨论】:

  • 你看过this
  • 我不是为 iPhone 开发的。
  • 它应该也适用于 Mac,就像 Dietrich 发布的那样。

标签: cocoa nsview


【解决方案1】:

一种选择是使StartScreen 成为NSViewController 的子类,也许将其名称更改为StartScreenController。如果您的 nib 文件中有 IBActions 和/或您想将视图控制代码放在它自己的类中,这可能是一个更加模块化的解决方案。

  1. StartScreenController 声明为NSViewController 的子类
  2. 如果需要,请在 StartScreenController 中声明 IBOutlets
  3. 将 nib 文件的所有者类设置为 StartScreenController
  4. 将文件的所有者view outlet 连接到视图对象,如果需要,还可以连接到其他 outlet

然后:

StartScreenController *ss = [[StartScreenController alloc] initWithNibName:@"nibname" bundle:nil];    
[self.window.contentView addSubView:ss.view];
…

如果您不使用垃圾回收,请不要忘记在不再需要时释放ss

【讨论】:

  • 好吧,这给了我一个错误:-[NSViewController loadView] loaded the "StartScreen" nib but no view was set. 但我最终解决了这个问题:我直接初始化和实例化一个 nib 并遍历其顶级对象以找到视图对象。 NSNib *nib = [[NSNib alloc] initWithNibNamed:@"StartScreen" bundle:nil]; StartScreen *ss = [[StartScreen alloc] init]; NSArray *aa; BOOL ok = [nib instantiateNibWithOwner: ss topLevelObjects: &aa]; aa 包含两个对象,一个是我需要的视图对象。
  • @Michael 你有这个错误是因为你错过了第 4 步:连接view 插座。
  • 感谢您的帮助!但我认为这比它应该的要复杂。我以不同的方式解决了它:我创建了自己的视图控制器类(NSObject 的子类),它自动执行笔尖加载内容。它还将视图连接到实例变量。我只需要在应用程序委托中执行StartScreen *ss = [[StartScreen alloc] init];[self.window.contentView addSubview: ss.view]; 即可,一切正常。甚至不需要指定笔尖名称。 -init 只是调用 +nibName 来获取 nib 名称,而我的默认实现只是返回类名。
  • @Michael 你基本上复制了NSViewController 已经为你做的事情,所以我不确定为什么使用NSViewController 更复杂。无论如何,任何适合你的!
【解决方案2】:

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

@implementation StartScreen
- (id) init {
    if ((self = [super init])) {
        if (![NSBundle loadNibNamed:@"StartScreen" owner:self])
            // error
        // continue initializing
    }
    return self;
}

NSBundle Additions reference

【讨论】:

  • 它还没有为我工作,但我想我发现了问题。我已将 StartScreen 类设为 NSView 的子类。但我认为它应该是 NSObject 的子类,对吧?但是我如何显示这个视图呢?我的意思是,我不能只在应用程序委托中调用 [self.window.contentView addSubView:],因为我没有看到视图对象,对吗?
  • (我怀疑它不应该是 NSView 的子类,因为您使用 -init 作为构造函数而不是 -initWithFrame :)
  • 我现在在 -initWithFrame: 构造函数中调用 loadNibNamed: 方法。我确认它被调用了,甚至 drawRect: 方法也被调用了,但是我没有在屏幕上看到 nib 文件的内容。
  • 为了显示一个视图,你必须把它放在一个窗口中。
  • 我知道 :-) 但是视图在哪里?正如 Bavarious 指出的那样,我没有连接视图插座。但最后,我不喜欢仅仅为了显示一个 nib 文件而做这么多的工作,所以我创建了自己的 Just Works (tm) 视图控制器类。只需要 70 行代码,包括空行和 cmets,就可以创建一个实际上比 NSViewController 更好的视图控制器类。使用 MyViewController,我不需要指定 nib 名称,也不需要连接视图插座。
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
相关资源
最近更新 更多