Initializing View Controllers in Swift
Swift beta 5 introduces some new rules that effect view controller subclasses and initializers. Subclasses are now required to implement init(coder aDecoder: NSCoder!)
even if it only calls super. What the compiler doesn't tell you is how you should initialize a view controller now. After trying a few things out, at least in a simple case, the following seems reasonable to me:
class MyViewController: UIViewController {
@IBOutlet var subview: UIView!
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
subview = UIView()
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
convenience override init() {
self.init(nibName: nil, bundle: nil)
}
}
I've made the one required property a strong, implicitly unwrapped IBOutlet. This allows my initWithNibName:
method to work as before. I've also added a convenience initializer so that I can omit (in init, get it?) passing nil for nib name and bundle. The class this code was extracted from is meant to be initialized in code but it would seem the days of just ignoring initWithCoder:
are over.
If you really don't want anyone using your view controller in a storyboard you might take the following approach I found on Stack Overflow:
required init(coder: NSCoder) {
fatalError("NSCoding not supported")
}
That seems almost spiteful though. If I have to implement the method anyway, and it doesn't take too much time, I might as well try to make it work. Who knows, someone might actually use it someday.
Let me know if I'm missing something. I can't wait to see how this all changes in beta 6.