2015-08-05 4 views
16

У меня есть экземпляр ViewController, определенный в раскадровке. Я могу инициализировать его следующимswift - Инициализировать контроллер просмотра из раскадровки, переопределяя init

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

Есть ли способ, чтобы переопределить метод инициализации из ViewController, так что я могу инициализировать его с помощью

var myViewController = ViewController() 

Я попытался перекрывая INIT

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

но компилятору это не нравится. Есть идеи?

+0

У меня нет решения, но почему вы хотите это сделать? – Caleb

+0

Он просто выглядит чище, я думаю. Плюс, если представление спроектировано в nib, оно работает автоматически, поэтому я могу перейти от раскадровки к наконечникам без изменения кода инициализации. – adamF

+0

Как просто создать собственный класс ViewController для каждого ViewController, который у вас есть? Это кажется мне намного более чистым. – Caleb

ответ

24

Инициализатор удобства всегда должен делегировать назначенный инициализатор для того же класса, и назначенный инициализатор должен вызывать инициализатор суперкласса.

Поскольку суперкласс не имеет соответствующий инициализатор, вы, вероятно, будете лучше обслуживаться с помощью метода класса фабрики:

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

затем использовать: фабричный метод

var myViewController = SearchTableViewController.instantiate() 
+3

в соответствии с инструкциями swift api - заводские методы следует начинать с «make». https://swift.org/documentation/api-design-guidelines/ – user1687195

11

класса является теперь можно идти. Вот протокол, который вы можете использовать для быстрого добавления поддержки instantiate() всем вашим UIViewController.

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 
     } 
    } 
} 

Пример:

extension MasterViewController: StoryboardInstantiable { 

    static var storyboardName: String { return "Main" } 
    static var storyboardIdentifier: String? { return "Master" } 
} 
Смежные вопросы