How to create and use a view from a xib

There are a number of reasons why you would want to create a view in a xib file. These are the most common ones: you want to reuse that view, your storyboard is too crammed, or maybe your want to avoid creating the view in code.

Although it sounds like a simple task, it is very cumbersome, especially if you are a beginner.

Let’s start!

I. Creating the view

First open the New File window (⌘N), go to User Interface, select View, then press Next.

After renaming it press Create. Now you have to create the class that goes with it. To do this, create a subclass of UIView, and give it the same name as the xib. I will name these files CustomView.

To connect the xib to the class go to the xib, select File’s Owner from Document Outline, then add the class in the Identity inspector.

Now for the tricky part. The view from the xib is not the same as the class one. Instead, you have to add the view from the xib as a subview to the class view.
Add these to CustomView.m:

// We’ll use this to store the view instantiated from the xib
@property (strong, nonatomic) UIView *xibView;

// Instantiates and returns the view from the xib
- (UIView *)loadViewFromNib {
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    UINib *nib = [UINib nibWithNibName:”CustomView” bundle:bundle];
    UIView *xibView = (UIView *)[nib instantiateWithOwner:self options:nil][0];
    return xibView;
}

// Stores the view from the xib, configures it, then adds it as a subview to CustomView.
- (void)xibSetup {
    self.xibView = [self loadViewFromNib];
    self.xibView.frame = self.bounds;
    self.xibView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self addSubview:self.xibView];
}

Now you just have to override the initializers so that they call -xibSetup.
-initWithFrame: is used when creating a view in code and -initWithCoder is called when the view is created in the Interface Builder. To avoid later bugs, implement both of them.

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (!self) return nil;

    [self xibSetup];

    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (!self) return nil;

    [self xibSetup];

    return self;
}

II. Designing the view.

At this point you can use CustomView, but it’s still empty. Go to CustomView.xib. As default
the view is shown as in full screen. If you want to change its size go to the Attributes inspector, select Freeform at Size and None at Status Bar.

Now drag&drop items on it to achieve the wanted design, just like in the storyboard. Don’t forget to add the constraints for Autolayout. Control-drag from these items to CustomView.h or CustomView.m to add outlets to the class, just like you would do in a controller.

You can now use CustomView either in code or in Interface Builder. To use it in the storyboard drag a generic view where you would want the CustomView to be and set its class to CustomView in the Identity inspector.

Useful tips:

  • Normally the generic view remains white although its class is set to CustomView, but you can make the CustomView to be shown by putting IB_DESIGNABLE in front of @interface

  • Furthermore, you can edit some properties of CustomView directly from the Attributes inspector if you write  in front of them.

You can download the sample project from here: https://github.com/IustinBulimar/ViewFromXib

Leave a Reply

You must be logged in to post a comment.