如何使用NSBundle loadNibNamed加载多个nib文件:?

时间:2010-08-26 17:28:16

标签: ios objective-c uikit interface-builder

我正在尝试通过调用loadNibNamed来加载我的视图层次结构。

对于单个笔尖,在我的ApplicationViewController : UIViewController

- (void) loadView {
    [super loadView];
    [[NSBundle mainBundle] loadNibNamed:@"ApplicationViewController" 
                                  owner:self options:nil];
}

然后在SubViewController : ApplicationViewController

- (void) loadView {
    [super loadView];
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
                                  owner:self options:nil];
}

当我初始化SubViewController时,视图只包含自己的nib文件,如何从super获取文件?

我试图将从调用返回的对象插入到NSBundle,回到调用的UIViewController自己的视图层次结构中,但这没有用完,一些强制转换问题使我无法调试这个...

3 个答案:

答案 0 :(得分:5)

您的示例中可能发生的情况是,在两个nib文件中,您正在设置view插座。然后会发生的是第二个加载的nib文件将覆盖第一个nib文件设置的view属性的值:

@implementation SubViewController

- (void) loadView
{
    [super loadView];
    // at this point, self.view points to the view loaded from
    // ApplicationViewController.nib
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
                              owner:self options:nil];
    // but at this point, self.view is overwritten with the view from
    // SubViewController.nib
}
...
@end

所以你可以这样做:在你的SubViewController类中,声明一个不同的插座,如下所示:

@property (nonatomic, retain) IBOutlet UIView* viewForSubController;
//you can probably think of a better name for it.

并且在您的xib文件中,没有设置view属性,而是设置了viewForSubController。然后在loadView做类似的事情:

@implementation SubViewController

- (void) loadView
{
    [super loadView];
    // at this point, self.view points to the view loaded from
    // ApplicationViewController.nib
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
                              owner:self options:nil];
    // now, self.viewForSubController points to the view loaded from
    // SubViewController.nib

    // so now we can do this:
    [self.view addSubview: self.viewForSubController];
}
...
@end

或类似的东西。

答案 1 :(得分:2)

首先,我通常使用以下内容加载Nib,然后将该控制器分配给其父控制器的保留成员...

self.myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];

因此每个视图控制器都会加载包含的视图控制器。然后您可能需要或不必通过调用显式将控制器视图(myViewController.view)添加到父级:

[window addSubview: myController.view];

您可能需要查看Apple的QuartzDemoUICatalog,以获取加载大量子视图控制器的代码示例,尽管它会将其添加到列表而不是视图中。

答案 2 :(得分:0)

你真的不应该从loadView中的nib加载。覆盖该方法的目的是以编程方式创建自己的视图。您可以从标准init调用initWithNibName:但听起来您正在尝试将两个视图组合在一起。我认为子类化不会按照你想要的方式去做。您可以让父视图加载子视图,并将其视图属性添加到父视图层次结构中。那是你想要做的吗?