By Blake Lucchesi on April 27, 2014

Building reusable views with Interface Builder and Auto Layout

Today I’d like to share the approach I’ve taken to making views reusable so that I can embed them inside of larger views. I found this to be a surprisingly difficult thing to accomplish, especially when trying to keep auto layout constraints in place. Adding the reusable view into a larger xib was quite simple but getting the objects I had wired up via IBOutlet for some reason never got initialized. If you had trouble with this as well, keep reading.

A visual to explain more clearly what we’re trying to accomplish:

adding a xib inside of another xib

Above wireframe made with Wireframe.cc

Create MyBannerView class and xib file:

  1. Create a new file using “File -> New -> New File” (cmd + N), select “Cocoa Touch” and then “Objective-C class”, then enter your desired filename, in our case MYBannerView and be sure to set the “Subclass of” value to “UIView”. I do recommend the filename to end in View so that the slightly less-caffeinated version of yourself remembers that its a view two months from now.
  2. Create another new file, this time choosing “User Interface” and then “View”. I would recommend you use the same name as before: MYBannerView.

Wiring up our outlets for MYBannerView.xib

The first step is to make a few adjustments to the pre-created xib file. The most important steps being to set the class name of the “File’s Owner” property and the other being to set the reference from the “View” to the “File’s Owner”.

  1. We must now configure our “File’s Owner” property for the xib. Click on the “File’s Owner” object, use the right hand inspector and change the class name to the name from step 1. (see screenshot below)

    Adjusting the File's Owner property

  2. Open up MYBannerView.h and add a new IBOutlet property so that we have a container within which it can setup Auto Layout constraints. Your file should look like this:

      @interface MYBannerView : UIView
      @property (nonatomic, weak) IBOutlet UIView *view;
  3. Now open up the MYBannerView.xib so we can connect the empty “View” that was created for you by Interface Builder to our newly added property. You can do this by selecting the “View” object in the list on the left, then selecting the “Connections Inspector” item from the right hand side. Then drag “New Referencing Outlet” back over to the “File’s Owner”. (Note: This can be done a few different ways, read up more on Interface Builder if you aren’t familiar with what we’re doing here).

    Connect a new referencing outlet to the View

MYBannerView initialization

Next we must add some code to our MYBannerView.m file so that when it is loaded by the outer xib file (MYViewController.xib) all of our outlets are properly loaded and we have a fully initialized view.

- (instancetype)initWithCoder:(NSCoder *)aDecoder
    self = [super initWithCoder:aDecoder];
    if (self) {
        NSString *className = NSStringFromClass([self class]);
        self.view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject];
        [self addSubview:self.view];
        return self;
    return nil;

Breaking it down:

Realizing the fruits of our labor

Now that we have a re-usable view there are just a few things to remember to do each time you add it to a larger view file.

  1. Drag a “UIView” object into the scene
  2. Make sure to edit the class name for the UIView object to your custom class, in our case MYBannerView
  3. Optionally, if you need to refer to the custom view from within your outer view’s code, you might want to add a @property definition for it. A la:

      @property (nonatomic, weak) IBOutlet MYBannerView *bannerView;

How it will look when you drag our re-usable subview into the outer View Controller xib: Adding the re-usable view into another xib

Wrapping up

This technique can make your life much simpler when it comes to creating reusable components. Most notably, it lets you design your views with interface builder using the code saving auto layout system. However, there are a few pitfalls to be aware of:

That wraps it up for this week. Thanks for reading and as always, I’d love to hear your tips on building a reusable view with a xib based implementation.

comments powered by Disqus