swift-通过重写init从故事板初始化视图控制器

swift-通过重写init从故事板初始化视图控制器,swift,uiviewcontroller,storyboard,init,Swift,Uiviewcontroller,Storyboard,Init,我在故事板中定义了一个ViewController实例。我可以通过以下方式初始化它 var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController 是否有方法重写ViewController的init方法,以便使用 var myViewController

我在故事板中定义了一个ViewController实例。我可以通过以下方式初始化它

var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController
是否有方法重写ViewController的init方法,以便使用

var myViewController = ViewController()
我试图重写init

convenience init() {
    self = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}

但是编译器不喜欢这样。有什么想法吗?

方便的初始值设定项必须始终委托给同一类的指定初始值设定项,并且指定的初始值设定项必须调用超类初始值设定项

由于超类没有适当的初始值设定项,因此最好使用类工厂方法:

static func instantiate() -> SearchTableViewController
{
    return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
然后使用:

var myViewController = SearchTableViewController.instantiate()

类工厂方法是目前的发展方向。这里有一个协议,您可以使用它快速将
makeFromStoryboard
支持添加到所有
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
        }
    }
}

例如:

extension MasterViewController: StoryboardInstantiable {

    static var storyboardName: String { return "Main" }
    static var storyboardIdentifier: String? { return "Master" }
}
如果视图控制器是情节提要中的初始视图控制器,您可以简单地忽略
情节提要标识符


如果所有视图控制器都在同一个情节提要中,您还可以覆盖
情节提要Instantiable
扩展名下的
情节提要名称
,并返回名称。

您可以尝试使用泛型。像这样:

func Tvc<T>(_ vcType: T.Type) -> T {
    let vc = (vcType as! UIViewController.Type).vc//限制或明确为 UIViewController.Type
    return vc as! T
}

extension UIViewController {
    fileprivate static var vc: UIViewController {
        let M = UIStoryboard.init(name: "V", bundle: Bundle.main)
        return M.instantiateViewController(withIdentifier: "\(self)")
    }
}

我没有解决办法,但你为什么要这样做?我想它看起来更干净。另外,如果视图是在nib中设计的,那么它会自动工作,这样我就可以在不更改初始化代码的情况下从故事板转到nib,如何为您拥有的每个ViewController创建一个自定义ViewController类?这对我来说似乎干净多了。到目前为止我就是这么做的。ViewController是一个自定义子类,但我仍然必须使用Storyboard对其进行初始化封装是一件好事,根据swift api指南,工厂方法应该以“make”开头。
let vc = Tvc(HLCases.self)
_vc.navigationController?.pushViewController(vc, animated: true)