IB: load outlets in Swift `init`
| Originator: | benchatelain | ||
| Number: | rdar://22771780 | Date Originated: | 19-Sep-2015 02:53 PM |
| Status: | Dup of 19950024 | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode 7 |
| Classification: | Enhancement | Reproducible: | Always |
This is a duplicate of rdar://19950024
Instantiating a view controller with Storyboard.instantiateViewControllerWithIdentifier has multiple problems. It exposes unnecessary implementation details to presenting view controllers, or necessitates boiler plate `createInstance` class methods. Instead, I should be able to load outlets from IB in a view controller's `init` method (in Swift). I should be able to do the same with table/collection cells.
This would give us the added benefit of being able to subclass IB-designed view controllers or views to add/alter behavior and use them in different settings.
Currently to instantiate a view controller from a storyboard in code, I have to use
Storyboard.instantiateViewControllerWithIdentifier. This means that I cannot provide an init method to pass in dependencies (such as model objects). Furthermore, my dependencies have to be Optional (either implicitly unwrapped or straight up Optional), and I don't have the benefit of having the Swift compiler ensure that my instance properties are set in init.
Instead, what if this method were available on UIViewController:
init(storyboard storyboard: UIStoryboard,
identifier: String)
This method should behave basically the same as the existing method for nib files:
init(nibName nibNameOrNil: String?,
bundle nibBundleOrNil: NSBundle?)
Now my subclass can look like this:
let viewModel:MyViewModel // yay for non-Optional let
public init(viewModel viewModel:MyViewModel) {
self.viewModel = viewModel // compiler makes sure we do this
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
super.init(storyboard:storyboard, identifier:"MyViewController")
}
Of course, IBOutlets will still need to be Optional (usually implicitly unwrapped) since those are set in ObjC and the swift compiler can't enforce the typical safety. I'll have to trust Apple to get that right. My properties, however, can benefit from the new safety provided by Swift: they can be non-optional constants.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!