Loading a nib within a storyboard
Earnest recently released its first iOS app. Below I share some details of how we engineered it.
Nibs and storyboards can’t seem to get along.
Imagine an iOS app that uses a storyboard for laying out view controllers. At some point you want to make a UIView subclass called MyView, implement its layout with a nib, and have it appear in a view controller in your storyboard. After creating MyView, you drag a UIView object into a view controller, and change the UIView’s class to MyView. ‘Done!’ you think to yourself. You run your app expecting to see the fruits of your labor, but instead you just see blank space.
The issue is that the storyboard ignores the nib by default. Therefore you need to take some additional configuration steps.
You’ll find several well-upvoted responses on stack overflow detailing approaches on the least-worst way to configure a nib to appear in a storyboard: creating a container in storyboard, reattaching outlets manually to a new instance, or creating another UIView to contain the subviews.
I find these to be too much. I have to repeat one of these procedures every time I use my custom nib, and what if I miss a step?
When using a UIView subclass with a programmatic layout, there are only three steps. I make the layout, drag a UIView object onto my view controller, then set my custom subclass. That just works. I want that behavior from my nib views:
I don’t want:
- Boilerplate code for each nib and/or view controller.
- Extra views floating about.
- To wrap my nib in anything else.
I want:
- All the constraints added on a storyboard to work.
- Any subviews added via a storyboard to appear.
- Any UIView properties set via a storyboard to be applied.
Check out the Swift ESTNib UIView extension.
To use, simply add the extension to your project and give your nib the same name as your subclass (i.e. MyView.swift & MyView.nib).
How does it work?
The extension overrides awakeAfterUsingCoder in cases where a nib file exists with the same name as the present class. It creates a new instance of the view with the nib, transfers the properties and constraints from the original nib to the new instance, and returns the new instance for the view controller to display.
Special thanks to Sunnyxx, creator of XXNibBridge, an Objective-C project with similar goals. Key differences between the two projects include
- ESTNib transfers the properties of your NSLayoutConstraints.
- ESTNib does not require your views to conform to a protocol.
- ESTNib works via an override while XXNibBridge uses swizzling.
- ESTNib supports storyboard-added subviews and their constraints.
Future improvements
ESTNib should be able to reflect custom IBInspectable storyboard properties from your UIView subclass as well.
Check us out
Earnest launched our iOS app today! For our current clients it’s a great way to manage your loan with Earnest and refer friends. For everyone else, you can get started with an affordable student loan refinance or personal loan. Download it free here!