Loading Nibs in iOS
Sometimes, in iOS development, you may want to load a Nib from a Storyboard, in this article I’m going to outline some different ways of achieving this.
Method 1
This might be the classic method that most people use.
class ViewController: UIViewController { override function viewDidLoad() {
super.viewDidLoad() if let nib = Bundle.main.loadNibNamed("View", owner: self),
let nibView = nib.first as? UIView {
nibView.frame = view.bounds
nibView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(nibView)
}
}}
Pretty straightforward, when the view controller’s view loads you load up the nib from the bundle, grab its first view (Nibs can have multiple views in them) and then add it as a subview to the view controller’s view.
If you want to setup some IBOutlets on the view controller for this view you’d set the ‘file owner’ in the Nib to be ‘ViewController’.
Method 2
Here’s an alternative. You may not be aware but UIViewController has a function called loadView(). We can override this function and set the view property to whatever we choose.
class ViewController: UIViewController {
override func loadView() {
super.loadView() if let nib = Bundle.main.loadNibNamed("View", owner: self),
let nibView = nib.first as? UIView {
view = nibView
}
}}
Quite similar to Method 1 but we get to set the view controller’s view to our desired view, rather than adding it as a subview, so there’s one less view in the hierarchy.
Method 3
Another spin on method 2 is to not load the nib in UIViewController’s loadView() function but to create a custom View class there instead.
class ViewController: UIViewController {
override func loadView() {
super.loadView() view = CustomView()
}}
Then, we load the nib in CustomView’s initialiser.
class CustomView: UIView { override init(frame: CGRect) {
super.init(frame: frame) if let nib = Bundle.main.loadNibNamed("View", owner: self),
let nibView = nib.first as? UIView {
nibView.frame = bounds
nibView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(nibView)
}
}}
This method is a bit less optimal than method 2, the resulting view hierarchy is similar to that of method 1. This isn’t really going to be an issue at the view controller level, but if you’re loading many nibs into a single view hierarchy you could end up with additional, unnecessary wrapper views that could impact performance a little.
If you want to setup some IBOutlets on the CustomView class for this view you’d set the ‘file owner’ in the Nib to be ‘CustomView’.
Method 4
This method is very similar to method 2 in that it results in the same (slightly more optimal) view hierarchy. In your storyboard you simply set the view controller’s root view’s class to your CustomView class (as defined in method 3) and it will effectively do the same as method 2.
This method is the only one that requires you to have a storyboard. A slight benefit of this approach is that it also doesn’t require you to have a UIViewController sub-class defined to get the Nib loaded. So if your view controller would otherwise be empty this method would allow you to do away with it and avoid bloating your codebase.
Fin
Those are the most notable ways I’m aware of, did I miss any? Do you have a preference or other pros/cons?