无法在Swift中的Storyboard中加载UIViewController XIB文件。
无法在Swift中的Storyboard中加载UIViewController XIB文件。
我阅读了 Using XCode storyboard to instantiate view controller that uses XIB for its design,但在 Swift 中(使用 Xcode 6 Beta 6)我遇到了麻烦。我想知道我做错了什么或者这个功能是否不再可用?
我创建了一个简单的存储库,https://github.com/jer-k/StoryboardTesting-Swift,展示了上述方法。
我通过添加 override 到 init 来解决了这个问题。
required init(coder aDecoder: NSCoder) { super.init(nibName: "TestViewController", bundle: NSBundle.mainBundle()) }
但我想知道是否仍然有可能让 storyboard 为我处理这个问题。创建一个超类让所有的 UIViewControllers 继承并包含上述代码并不是世界上最繁琐的事情,但此时我只是好奇。
另一个答案是:
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/
编辑:
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,谁知道呢...)
所发生的情况是,Seed 5 打破了一个机制,即当视图控制器是 Swift 类时,该控制器可以通过名称找到其 xib 文件。原因是 Swift 认为类的名称与您所给出的名称(以及您给出的 xib 文件的名称)不同;名称已被“操纵”,特别是通过添加模块名称(即 Swift 类具有命名空间)。
我提供了三种解决方法:
-
您的解决方法很好(显式按名称加载 .xib 文件)
-
将 .xib 文件命名为 MyModule.TestViewController.xib,其中 MyModule 是您的包(即项目名称)的名称(这是 Apple 建议的方法,但我不喜欢)
-
在视图控制器的 class 声明之前使用
@objc(TestViewController)
来克服名称操纵,这是破坏机制的原因(这是我喜欢采取的方法)
请参阅我在此处的讨论:https://stackoverflow.com/a/25163757/341994 和我从那里链接到的进一步讨论:https://stackoverflow.com/a/25152545/341994
编辑:iOS 9 beta 4 已经修复了这个错误。如果 nib 文件搜索失败,iOS 9 现在会剥离视图控制器类名的模块名称并再次执行 nib 文件搜索。