Не удается загрузить файл UIViewController XIB в раскадровке в 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 унаследовали от вышеуказанного кода, не самая громоздкая вещь в мире, но мне просто любопытно на данный момент.

2 ответов


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

Я предлагаю три способа:

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

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

  • использовать @objc(TestViewController) перед контроллером вида class декларация для преодоления искажения имени, которое является тем, что нарушает механизм (это подход I favor)

см. мое обсуждение здесь: https://stackoverflow.com/a/25163757/341994 и моего дальнейшего обсуждения, ссылки на которые есть: https://stackoverflow.com/a/25152545/341994

редактировать эта ошибка исправлена в iOS 9 beta 4. Если поиск файла nib не удается, iOS 9 теперь удаляет имя модуля с имени класса контроллера вида и выполняет поиск файла nib во второй раз.


еще один ответ:

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 тоже, кто знает...))