I have a ViewController instance defined in a storyboard. I can initialize it by the following
var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController
Is there a way to override the init method of ViewController so that I can initialize it using
var myViewController = ViewController()
I tried overriding init
convenience init() {
self = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
but the compiler doesn't like that. Any ideas?
In the Storyboard, select the view controller that you want to instantiate in code. Make sure the yellow circle is highlighted, and click on the Identity Inspector. Set the custom class as well as the field called "Storyboard ID". You can use the class name as the Storyboard ID.
A convenience initializer must always delegate to a designated initializer for the same class, and a designated initializer must call a superclass initializer.
Since the superclass doesn't have an appropriate initializer, you would probably be better served by a class factory method:
static func instantiate() -> SearchTableViewController
{
return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
then use:
var myViewController = SearchTableViewController.instantiate()
A class factory method is the way to go for now. Here's a protocol that you can use to quickly add makeFromStoryboard
support to all UIViewController
s.
protocol StoryboardInstantiable {
static var storyboardName: String { get }
static var storyboardBundle: NSBundle? { get }
static var storyboardIdentifier: String? { get }
}
extension StoryboardInstantiable {
static var storyboardBundle: NSBundle? { return nil }
static var storyboardIdentifier: String? { return nil }
static func makeFromStoryboard() -> Self {
let storyboard = UIStoryboard(name: storyboardName, bundle: storyboardBundle)
if let storyboardIdentifier = storyboardIdentifier {
return storyboard.instantiateViewControllerWithIdentifier(storyboardIdentifier) as! Self
} else {
return storyboard.instantiateInitialViewController() as! Self
}
}
}
Example:
extension MasterViewController: StoryboardInstantiable {
static var storyboardName: String { return "Main" }
static var storyboardIdentifier: String? { return "Master" }
}
In case the view controller is the initial view controller in the storyboard, you can simply ignore storyboardIdentifier
.
In case all the view controllers are in the same storyboard, you can also override storyboardName
under the StoryboardInstantiable
extension and return the name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With