Swift - Инициализировать контроллер просмотра из раскадровки, переопределив init

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

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

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

var myViewController = ViewController()

Я попробовал переопределить init

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

но компилятору это не нравится. Любые идеи?

Ответы

Ответ 1

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

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

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

затем используйте:

var myViewController = SearchTableViewController.instantiate()

Ответ 2

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

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