[iOS] Creating reusable UIViews with Storyboard

[iOS] Creating reusable UIViews with Storyboard

onedayitwillmake 6 comments
iOS sourcecode

I’m a big fan of using Storyboards to act as the glue for your application.
It just makes everything much easier, and makes your program feel like a cohesive application instead of a random assortment of UIViewControllers

However one problem is that, Storyboards don’t lend themselves to having reusable views.
Which I find kind of odd, because it seems common that you would have a view that needs to exist in multiple screens for myriad reasons in a lot of applications.

Wellp, it’s actually not that difficult to do – although definitely falls in the ‘tricky’ category.

(Scroll to bottom for TL;DR version)

To start, simply create a class that extends UIView
For the purposes of brevity, lets both call ours SharedView.
Screen Shot 2013-07-14 at 3.58.35 PM

Now, create a nib of it.
I like to use the exact same name as the class since it makes it easier to determine what goes with what 6 months later.
Screen Shot 2013-07-14 at 4.01.05 PMScreen Shot 2013-07-14 at 4.01.28 PM

Well that doesn’t really help us very much!
It looks completely wrong and it’s not even aware that it’s connected to anything.
The real benefit of InterfaceBuilder is the ability to flesh out your views visually so that your code doesn’t have tons of non-interesting interface declarations in it.

Setting up the view
The first thing we have to do is go to the attributes inspector on the right.
1. Set the size to free form
2. Set the status bar to none
3. Go to the metrics size inspector, and set the size to whatever you like after

Screen Shot 2013-07-14 at 4.04.23 PM

Connecting the view
1. Select the File’s owner property on the left hand side under ‘Placeholders
Screen Shot 2013-07-14 at 4.15.52 PM
2. Set the custom class from ‘NSObject’ to our shared view
Screen Shot 2013-07-14 at 4.07.16 PM
3. Turn on the Assistant Editor, and you should see your class’s header fiee on the right.
4. Drag the view itself onto the header class, and call it “contentView
Screen Shot 2013-07-14 at 4.17.44 PM
5. In the class’s implementation file remove ‘initWithCoder’ and replace it with the following:

-(void)awakeFromNib {
    //Note That You Must Change @”BNYSharedView’ With Whatever Your Nib Is Named
    [[NSBundle mainBundle] loadNibNamed:@"MLQuadButton" owner:self options:nil];
    [self addSubview: self.contentView];
}

Note that you must change @”BNYSharedView’ with whatever your nib is named

This places content inside of our view, the downside to this method is that it does create an extra layer of view-hierarchy. If you were diametrically opposed to this, you could simply loop through self.contentView and add all it’s children to your view instead. But I find that to be a bit of an overkill and more confusing.

Connecting IB Outlets in our custom class
Let’s add a random label for demonstration.

  1. Drag the label to the view, and in it type ‘I am a shared view’
    Screen Shot 2013-07-14 at 4.12.05 PM
  2. Holding down the right-click and drag the label onto the header file (before @end) and connect it as an outlet.
    Screen Shot 2013-07-14 at 4.12.29 PM

You can now access this label inside of your awakeFromNib method. Just as you would IB outlets normally.

Using the view
Simply create a UIView inside of your storyboard, and set it’s class to our ‘SharedView’ class.
Note: Remember to set match the frame size to whatever dimensions you made your view in IB

TL;DR

  1. Create a class named SharedView which extends UIView
  2. Create a nib with the same name
  3. Set the ‘File’s Owner’ property in the nib to the SharedView class
  4. Create an outlet from your view to the SharedView class, and call it ‘contentView’
  5. Replace initWithCoder with the following:
    -(void)awakeFromNib {
    //Note that you must change @”BNYSharedView’ with whatever your nib is named
        [[NSBundle mainBundle] loadNibNamed:@"BNYSharedView" owner:self options:nil];
        [self addSubview: self.contentView];
    }
  6. In your ViewControllers create views, and set their class to SharedView

6 Comments

Carl Carlson

November 24, 2013 at 11:39 pm

This is very helpful. Reusable views created in IB work just fine.

I need to create these reusable views via code. Calling awakeFromNib creates them, but they don’t respond to gestureRecognizers like they should. They don’t call drawRect whey they are created, but do after I double touch them.

Any ideas?

Thanks,

Carl Carlson

 Reply

Carl Carlson

November 26, 2013 at 1:11 am

Never mind. Sigh! Sorry for the stupid question

 Reply

Clay

November 27, 2013 at 12:41 am

I’ve tried this solution with a UITabBarController and it seems to break. Add two UIViewControllers to a tab bar. Then, create a re-usable UIView that has a UIButton on it.

Add the UIView to the first presented UIViewController. Try to hit the button… it doesn’t work. Now, try navigating to the next Tab, and then go back. The button works…

 Reply

Brandon

February 8, 2014 at 7:16 pm

Thank you, I was struggling to implement this until I found your explanation.

 Reply

Nirbhay Agarwal

July 21, 2014 at 10:06 am

Great tutorial! Thanks

 Reply

ios-creating-reusable-uiviews-with-storyboard – Part 2 | Onedayitwillmake

September 25, 2014 at 11:22 am

[…] has is an updated version of ios-creating-reusable-uiviews-with-storyboard for Xcode […]

 Reply

Leave a Reply


*