无法在Swift中的Storyboard中加载UIViewController XIB文件
我读过使用XCode storyboard来实例化视图控制器,它使用XIB的devise,但我有麻烦使这个工作在Swift(使用Xcode 6 Beta 6)。 我想知道如果我做错了什么,或者如果这个function不可用?
我创build了一个简单的存储库, https://github.com/jer-k/StoryboardTesting-Swift ,展示了上面的方法。
我设法通过添加并覆盖到init来解决问题
required init(coder aDecoder: NSCoder) { super.init(nibName: "TestViewController", bundle: NSBundle.mainBundle()) }
但我想知道是否还有可能让故事板为我处理。 创build一个超类让所有的UIViewControllersinheritance上面的代码并不是世界上最麻烦的事情,但我只是好奇于此。
发生了什么是Seed 5破坏了视图控制器可以通过名称find它的xib的机制,如果视图控制器是一个Swift类。 原因是在Swift的脑海里,这个类的名字和你给的名字(和你给xib文件的名字)是不一样的。 该名称已被“mangled”,特别是通过预先模块名称(即Swift类具有命名空间)。
我提供了三种解决方法:
-
你的解决方法是一个好的(显式加载.xib文件的名字)
-
命名.xib文件MyModule.TestViewController.xib ,其中
MyModule
是你的包的名称(即项目的名称)(这是苹果的build议,但我讨厌它) -
在视图控制器的
class
声明之前使用@objc(TestViewController)
来克服这个打破机制的名字(这是我喜欢的方法)
看到我的讨论在这里: https : //stackoverflow.com/a/25163757/341994和我的进一步讨论链接从那里: https : //stackoverflow.com/a/25152545/341994
编辑这个bug在iOS 9 beta 4中修复。如果nib文件search失败,iOS 9现在将模块名称从视图控制器类名称中剥离出来,并再次执行nib文件search。
另一个答案是:
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上,谁知道…))