Creating a generic UViewController initializer
I am trying to create an extension UIViewController
that I can use to initialize new instances. For each view controller in my project, I have a corresponding storyboard.
i.e.
EditSomethingViewController.swift
EditSomethingViewController.storyboard
This is what I have so far:
extension UIViewController {
static func initalize() -> UIViewController? {
let name = String(self)
let storyboard = UIStoryboard(name: name, bundle: nil)
return storyboard.instantiateInitialViewController()
}
}
However, this means that when I use it, I still need to return an answer.
i.e.
if let viewController = EditSomethingViewController.initalize() as? EditSomethingViewController {
// do something with view controller here
}
Is it possible to create an extension in such a way that I cannot give an answer?
ps Working on an old project written in Swift 2.3 would appreciate the answers that are supported.
source to share
I am using this extension:
extension UIViewController
{
class func instantiateFromStoryboard(_ name: String = "Main") -> Self
{
return instantiateFromStoryboardHelper(name)
}
fileprivate class func instantiateFromStoryboardHelper<T>(_ name: String) -> T
{
let storyboard = UIStoryboard(name: name, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: String(describing: self)) as! T
return controller
}
}
Using:
let controller = MyViewController.instantiateFromStoryboard()
source to share
You can change the return type as Self
to match the type you are calling the method on.
This is the method I used to do this. Instead, it should be placed in a protocol extension.
static func loadFromStoryboard() -> Self? {
let storyboard = UIStoryboard(name: NSStringFromClass(self),
bundle: Bundle(for: self))
return storyboard.instantiateInitialViewController() as? Self
}
source to share
I assume you don't want each of your VCs to manually match the protocol. It will be too much work :)
I haven't tested this, but this should work:
protocol Initializable {
static func initalize() -> Self?
}
extension UIViewController: Initializable {
static func initalize() -> Self? {
let name = NSStringFromClass(self as! AnyClass)
let storyboard = UIStoryboard(name: name, bundle: nil)
return storyboard.getInitialVC(type: self)
}
}
extension UIStoryboard {
func getInitialVC<T: UIViewController>(type: T.Type) -> T? {
return instantiateInitialViewController() as? T
}
}
source to share