Creating a generic UViewController initialiser

此生再无相见时 提交于 2019-12-01 06:47:56

I use 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
    }
}

Usage:

let controller = MyViewController.instantiateFromStoryboard()

I assume that you don't want to make every one of your VCs conform to a protocol manually. That would 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
    }
}

You can change the return type to be Self which will match the type you are calling the method on.

This is a method I've used to do this. It will need to be put into a protocol extension instead.

static func loadFromStoryboard() -> Self? {
    let storyboard = UIStoryboard(name: NSStringFromClass(self),
                                  bundle: Bundle(for: self))
    return storyboard.instantiateInitialViewController() as? Self
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!