Iraklis Panagiotidis
Iraklis Panagiotidis

Reputation: 151

inherit xib-file in Interface Builder

I have a ViewController.xib made in IB, that has a UITableView. I want to build another xib-file e.g. SearchViewController.xib, thas inherit from ViewController.xib. The new SearchViewController.xib should inherit the UITableView and additionally it should have a UISearchBar and a UIButton.

It's possible to make this scenario with the Interface Builder?

Upvotes: 15

Views: 6169

Answers (6)

Mike M
Mike M

Reputation: 5122

The way to think about it is that a XIB file is a serialised object and not a class. An instance of a class (i.e. an object) cannot be subclassed, except from some prototype based languages like Javascript.

One way of mocking this however is by creating a parent class of UIView type which will load the XIB and add it to itself (remember that a XIB contains an NSArray of visual elements).

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:self options:nil];
        UIView* mainView = (UIView*)[nibViews objectAtIndex:0];
        self.label.text = @"Parent";
        [self addSubview:mainView];
    }
    return self;
}

The Child can then simply override the initialiser as

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.label.text = @"Child";
    }
    return self;
}

The self.label is of course linked to a UILabel in the XIB file via interface builder and connected at runtime via the owner:self argument.

Upvotes: 1

yershuachu
yershuachu

Reputation: 788

The problem is that subclass calls initWithNibName with it's class name.

I would go with forcing superclass to load the superclass xib always even if inherited (make sure that outlets are in .h of the super class)

in superclass override initWithNib (it will be called as well as normal init if you created xib based vc)

-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:@"NameOfTheSuperClass" bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}

Upvotes: 0

user843337
user843337

Reputation:

You could make use of a Container View in order to reuse a particular view controller. That way you only have to create it once, add the logic once and you can simply reuse the component where-ever you like:

enter image description here

This is Apples documentation on the Container View, hope it helps!

Upvotes: 4

Ali Amin
Ali Amin

Reputation: 687

It's really a problem should be taken care of in xCode's next versions .As you need to write in code your interface needed to be inherited in other classes which is a nightmare in case of modifications are required later .Or you can copy/paste xib file which will be also a nightmare as you'll need to open them all and apply modifications

Upvotes: 0

Jordan
Jordan

Reputation: 21760

You'll need separate .xib files or, use one as the default, then add the controls (e.g. SearchViewController, etc) programmatically in code.

Upvotes: 1

Ole Begemann
Ole Begemann

Reputation: 135548

No, there is no concept of inheritance among NIB files. Your only option is to duplicate the original file and make the necessary changes in the copy.

Upvotes: 10

Related Questions