Невозможно загрузить файл XIV UIViewController в раскадровке в Swift

Я читал Использование раскадровки XCode для создания экземпляра контроллера представлений, который использует XIB для его дизайна, но у меня возникают проблемы, связанные с этой работой в Swift (использование Xcode 6 Beta 6). Мне интересно, если я сделал что-то неправильно или эта функция больше не доступна?

Я создал простой репозиторий, https://github.com/jer-k/StoryboardTesting-Swift, который демонстрирует вышеупомянутый подход.

Мне удалось решить проблему, добавив и переопределив init

required init(coder aDecoder: NSCoder) {
    super.init(nibName: "TestViewController", bundle: NSBundle.mainBundle())
}

но мне интересно, возможно ли, чтобы раскадровка справилась с этим для меня. Создание суперкласса, чтобы унаследовать все мои UIViewControllers с указанным выше кодом, - это не самая громоздкая вещь в мире, но мне просто интересно на этом этапе.

Ответ 1

Что произошло, так это то, что Seed 5 нарушил механизм, посредством которого контроллер вида может найти свой xib по имени, если контроллер вида является классом Swift. Причина в том, что имя класса в ум Swift не совпадает с именем, которое вы ему дали (и именем, которое вы дали xib файлу); имя было "искалечено", в частности, добавив имя модуля (то есть классы Swift имеют пространство имен).

Предлагаю три метода:

  • Ваше обходное решение является хорошим (загрузите файл .xib по имени явно)

  • Назовите файл .xib MyModule.TestViewController.xib, где MyModule - это имя вашего пакета (то есть имя проекта) (это то, что Apple советует, но я его ненавижу)

  • Используйте @objc(TestViewController) перед объявлением контроллера class для преодоления искажения имени, что является нарушением механизма (это тот подход, который я предпочитаю)

Смотрите мою дискуссию здесь: fooobar.com/questions/15643/... и мое дальнейшее обсуждение связано с этим: fooobar.com/questions/15645/...

РЕДАКТИРОВАТЬ Эта ошибка исправлена ​​в бета-версии iOS 9 4. Если поиск файла nib завершился неудачно, iOS 9 теперь удаляет имя модуля из имени класса контроллера представления и выполняет второй раз поиск файла nib.

Ответ 2

Другой ответ:

override func loadView() {
    if #available(iOS 9, *) {
        super.loadView()
    } else {
        let classString = String(self.dynamicType)
        NSBundle.mainBundle().loadNibNamed(classString, owner: self, options: nil)
    }
}

ссылка: http://japko.net/2014/09/08/loading-swift-uiviewcontroller-from-xib-in-storyboard/

EDIT:

override var nibName: String? {
    get {
        let classString = String(self.dynamicType)
        return classString
    }
}
override var nibBundle: NSBundle? {
    get {
        return NSBundle.mainBundle()
    }
}

Это выглядит красивее. Работает на iOS 8/9 (возможно, на iOS 7 тоже, кто знает...))