2015-08-05 11 views
16

Ich habe eine ViewController-Instanz in einem Storyboard definiert. Ich kann es durch die folgendeswift - View-Controller vom Storyboard initialisieren durch Überschreiben von init

initialisieren
var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController 

Gibt es eine Möglichkeit, die init-Methode von Viewcontroller außer Kraft zu setzen, damit ich es initialisieren kann

var myViewController = ViewController() 

mit Ich versuchte zwingende init

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

aber der Compiler mag das nicht. Irgendwelche Ideen?

+0

Ich habe keine Lösung, aber warum sollte man dies tun wollen? – Caleb

+0

Es sieht einfach sauberer aus, denke ich. Plus, wenn die Ansicht in einer Nib entworfen wird, funktioniert es automatisch, so dass ich von Storyboards zu Nibs wechseln kann, ohne den Initialisierungscode zu ändern – adamF

+0

Wie wäre es, wenn Sie für jeden ViewController eine eigene ViewController-Klasse erstellen? Das scheint mir viel sauberer zu sein. – Caleb

Antwort

24

Ein Convenience-Initialisierer muss immer an einen designierten Initializer für dieselbe Klasse delegieren, und ein designierter Initializer muss einen Superclass-Initialisierer aufrufen.

Da die übergeordnete Klasse, keine geeignete initializer haben würden Sie wahrscheinlich besser durch eine Klasse Factory-Methode bedient werden:

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

dann verwenden:

var myViewController = SearchTableViewController.instantiate() 
+3

gemäß den Swift-API-Richtlinien - Factory-Methoden sollte mit "make" beginnen. https://swift.org/documentation/api-design-guidelines/ – user1687195

11

Eine Klasse Factory-Methode das ist Weg jetzt zu gehen. Hier ist ein Protokoll, mit dem Sie schnell instantiate() Unterstützung für alle Ihre UIViewController s hinzufügen können.

protocol StoryboardInstantiable { 

    static var storyboardName: String { get } 
    static var storyboardBundle: NSBundle? { get } 
    static var storyboardIdentifier: String? { get } 
} 
​ 
extension StoryboardInstantiable { 

    static var storyboardIdentifier: String? { return nil } 
    static var storyboardBundle: NSBundle? { return nil } 

    static func instantiate() -> Self { 
     let storyboard = UIStoryboard(name: storyboardName, bundle: storyboardBundle) 

     if let storyboardIdentifier = storyboardIdentifier { 
      return storyboard.instantiateViewControllerWithIdentifier(storyboardIdentifier) as! Self 
     } else { 
      return storyboard.instantiateInitialViewController() as! Self 
     } 
    } 
} 

Beispiel:

extension MasterViewController: StoryboardInstantiable { 

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