ストーリーボードで定義された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" }
}
ビューコントローラーがストーリーボードの最初のビューコントローラーである場合は、storyboardIdentifier
を単に無視できます。
すべてのView Controllerが同じストーリーボードにある場合は、storyboardName
拡張子の下のStoryboardInstantiable
をオーバーライドして名前を返すこともできます。