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

ada*_*amF 19 init storyboard uiviewcontroller swift

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

var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController
Run Code Online (Sandbox Code Playgroud)

有没有办法覆盖ViewController的init方法,以便我可以使用它初始化它

var myViewController = ViewController()
Run Code Online (Sandbox Code Playgroud)

我试过覆盖init

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

但编译器不喜欢这样.有任何想法吗?

Ste*_*ath 29

便捷初始化程序必须始终委托给同一类的指定初始化程序,并且指定的初始化程序必须调用超类初始化程序.

由于超类没有合适的初始化程序,因此类工厂方法可能会更好:

static func instantiate() -> SearchTableViewController
{
    return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
Run Code Online (Sandbox Code Playgroud)

然后使用:

var myViewController = SearchTableViewController.instantiate()
Run Code Online (Sandbox Code Playgroud)

  • 根据swift api指南 - 工厂方法应以"make"开头.https://swift.org/documentation/api-design-guidelines/ (6认同)

Ber*_*erk 15

类工厂方法是现在的方法.这是一个可以用来快速添加makeFromStoryboard对所有UIViewControllers的支持的协议.

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

extension MasterViewController: StoryboardInstantiable {

    static var storyboardName: String { return "Main" }
    static var storyboardIdentifier: String? { return "Master" }
}
Run Code Online (Sandbox Code Playgroud)

如果视图控制器是故事板中的初始视图控制器,则可以忽略storyboardIdentifier.

如果所有视图控制器都在同一个故事板中,您还可以storyboardNameStoryboardInstantiable扩展名下覆盖并返回名称.