2014-08-28 59 views
22

我读过Using XCode storyboard to instantiate view controller that uses XIB for its design,但我在Swift(使用Xcode 6 Beta 6)中遇到麻烦。我想知道我是否做错了什么,或者如果这个功能不再可用?无法在Swift中的Storyboard中加载UIViewController XIB文件

我创建了一个简单的存储库,https://github.com/jer-k/StoryboardTesting-Swift,展示了上述方法。

我设法通过增加来解决这个问题,并覆盖到初始化

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

但我想知道如果它仍然可能有故事板处理这对我来说。创建一个超类让所有的UIViewControllers继承上述代码并不是世界上最麻烦的事情,但我只是对此感到好奇。

+0

我想知道什么时候有人会问这个问题... :) – matt 2014-08-28 00:38:15

+0

http://stackoverflow.com/questions/27151026/无法编程地创建一个uiviewcontroller在迅速/ 35888118#35888118 – 2016-03-09 10:03:09

回答

39

发生了什么事是Seed 5打破了视图控制器可以通过名称找到它的xib的机制,如果视图控制器是Swift类的话。原因是在Swift的脑海里,这个类的名字与你给它的名字(和你给xib文件的名字)不一样。该名称已被“破坏”,特别是通过预先添加模块名称(即Swift类具有名称空间)。

我提供三种解决方法:

  • 你的解决方法是一个很好的

  • 名称的.xib文件(按名称显式加载的.xib文件)MyModule.TestViewController.xib,其中MyModule是你的包的名称(即项目名称)(这是苹果的建议,但我讨厌它)

  • 使用@objc(TestViewController) bef矿石视图控制器的class声明克服名字改编这是什么破机制(这是我喜欢的方式)

看到这里我的讨论:https://stackoverflow.com/a/25163757/341994和我进一步讨论挂在那里:https://stackoverflow.com/a/25152545/341994

编辑此错误在iOS 9 beta 4中得到修复。如果nib文件搜索失败,则iOS 9现在将模块名称从视图控制器类名剥离并再次执行nib文件搜索。

+0

我有一些轻微的希望,苹果将通过解决这个问题来回应我的错误报告,但事实上,他们用我的错误“令人沮丧。 – matt 2014-08-28 00:39:29

+0

我看到你的讨论第二个链接的答案,我明白了。是否记录过我们需要开始将模块名称预先添加到xibs中?也许我错过了它。无论哪种方式,令人敬畏的工作。我现在要使用@objc方法,因为如果他们决定放弃对前置模块名称的需求,它将很容易删除。如果我们退出测试版,并且最终确定我们必须预先输入模块名称,因为这是他们建议的方法,但现在我喜欢您的解决方案。 – TheJer 2014-08-28 00:45:45

+1

需要补充说明的是:我不得不回到故事板并重新设置名称来拾取未损坏的版本,但它的作用就像一个魅力。 – TheJer 2014-08-28 00:59:10

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/

编辑:

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上,谁知道......))

+0

第二个答案适用于我。现在我可以用iOS8模拟器进行测试 – iWheelBuy 2016-05-25 04:33:23

相关问题