Как использовать @IBSegueAction с UITabBarController?

У меня есть панель с двумя вкладками. Чтобы избежать дополнительных опций в контроллерах представления, я пытаюсь использовать@IBSegueAction.

Я инициализирую контроллер панели вкладок:

let tabBarController = storyboard.instantiateInitialViewController { coder in
    TabBarController(coder: coder, mainVar: (first: "Hello", second: "World"))
}

Я инициализирую два контроллера представления из класса контроллера панели вкладок:

class TabBarController: UITabBarController {

    let mainVar: (first: String, second: String)

    required init?(coder: NSCoder) {
        fatalError()
    }

    init?(coder: NSCoder, mainVar: (String, String)) {
        self.mainVar = mainVar
        super.init(coder: coder)
    }

    @IBSegueAction func instantiateFirstViewController(coder: NSCoder) -> UIViewController? {
        FirstViewController(coder: coder, firstVar: mainVar.first)
    }

    @IBSegueAction func instantiateSecondViewController(coder: NSCoder) -> UIViewController? {
        SecondViewController(coder: coder, secondVar: mainVar.second)
    }
}

А вот один из контроллеров представления:

class FirstViewController: UIViewController {

    let firstVar: String

    required init?(coder: NSCoder) {
        fatalError()
    }

    init?(coder: NSCoder, firstVar: String) {
        self.firstVar = firstVar
        super.init(coder: coder)
    }
}

Подключаю сегменты к соответствующим @SegueActions:

Моя проблема в том, что когда я запускаю проект, я получаю сбой:

Вместо использования моего инициализатора Xcode использует инициализатор по умолчанию. Сообщение об ошибке: [Storyboard] Unable to find method -[(null) instantiateFirstViewControllerWithCoder:]

Изменить: я загрузил полный демонстрационный проект на GitHub: демонстрационный проект

3 ответа

Это решение, описанное в следующей статье, отлично работает с UITabBarController а также UINavigationController. Не сUISplitViewController хотя.

https://useyourloaf.com/blog/using-ibsegueaction-with-tab-bar-controllers/

Коротко:

  • создать корень UIViewController (сказать RootViewController) с видом на контейнер
  • установите переход от представления контейнера к вашему UITabBarController
  • реализовать @IBSegueActionс в RootViewController например
@IBSegueAction
func makeFirstViewController(coder: NSCoder) -> UIViewController? { ... }
  • для сегментов, идущих от UITabBarController к его viewControllers, подключите действия segue к RootViewController

Я борюсь с этой ошибкой (да, я считаю, что это ошибка Apple) уже больше месяца. Я обошел это, создав только viewControllers в раскадровках (и в этом случае я могу.instantiateInitialViewController с моими параметрами). Что касается tabBarController, я создаю его программно, прикрепляя к нему экземпляры viewController в коде.

Вам нужно установить идентификатор для перехода в инспекторе атрибутов segue (он работал со встроенным переходом ContainerView, но я думаю, что это то же самое для других сегментов):

Другие вопросы по тегам