web-dev-qa-db-ja.com

swift-initをオーバーライドしてストーリーボードからView Controllerを初期化します

ストーリーボードで定義された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
}

しかし、コンパイラはそれを好きではありません。何か案は?

19
adamF

簡易イニシャライザは常に同じクラスの指定イニシャライザに委任する必要があり、指定イニシャライザはスーパークラス初期化子を呼び出す必要があります。

スーパークラスには適切な初期化子がないので、おそらくクラスファクトリメソッドのほうが適しています。

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

次に使用します:

var myViewController = SearchTableViewController.instantiate()
29
Steven McGrath

クラスファクトリメソッドは今のところ進むべき道です。以下は、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
        }
    }
}

例:

extension MasterViewController: StoryboardInstantiable {

    static var storyboardName: String { return "Main" }
    static var storyboardIdentifier: String? { return "Master" }
}

ビューコントローラーがストーリーボードの最初のビューコントローラーである場合は、storyboardIdentifierを単に無視できます。

すべてのView Controllerが同じストーリーボードにある場合は、storyboardName拡張子の下のStoryboardInstantiableをオーバーライドして名前を返すこともできます。

15
Berk