Невозможно загрузить файл 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 тоже, кто знает...))