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.
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.
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
Connecting the view
1. Select the File’s owner property on the left hand side under ‘Placeholders
2. Set the custom class from ‘NSObject’ to our shared view
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
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:@"BNYSharedView" 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.
- Drag the label to the view, and in it type ‘I am a shared view’
- Holding down the right-click and drag the label onto the header file (before @end) and connect it as an outlet.
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
- Create a class named SharedView which extends UIView
- Create a nib with the same name
- Set the ‘File’s Owner’ property in the nib to the SharedView class
- Create an outlet from your view to the SharedView class, and call it ‘contentView’
- 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]; }
- In your ViewControllers create views, and set their class to SharedView