【问题标题】:Can't Load UIViewController XIB file in Storyboard in Swift无法在 Swift 的 Storyboard 中加载 UIViewController XIB 文件
【发布时间】:2014-10-21 17:41:22
【问题描述】:

我已经阅读了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,它展示了上述方法。

我设法通过添加和覆盖 init 解决了这个问题

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

但我想知道是否仍然可以让故事板为我处理这个问题。用上面的代码创建一个超类来继承我所有的 UIViewController 并不是世界上最麻烦的事情,但我现在只是好奇。

【问题讨论】:

标签: ios uiviewcontroller swift storyboard xib


【解决方案1】:

如果视图控制器是 Swift 类,Seed 5 破坏了视图控制器可以通过名称找到其 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

EDIT 此错误已在 iOS 9 beta 4 中修复。如果 nib 文件搜索失败,iOS 9 现在会从视图控制器类名中去除模块名称并再次执行 nib 文件搜索.

【讨论】:

  • 我有点希望 Apple 会通过修复此问题来回应我的错误报告,但他们以“按预期工作”关闭了我的错误这一事实令人沮丧。
  • 我看到你的讨论是第二个链接的答案,我明白了。是否曾经记录过我们需要开始将模块名称添加到 xibs 上?也许我错过了。无论哪种方式,很棒的工作。我现在将使用@objc 方法,因为如果他们决定放弃对前置模块名称的需求,它将很容易删除。如果我们从测试版出来并且最终确定我们必须预先添加模块名称,我可能会切换,因为这是他们建议的方法,但现在我喜欢你的解决方案。
  • 需要补充一点:我必须回到情节提要并重新设置名称才能获得未损坏的版本,但它就像一个魅力。
  • @StevenHernandez 那你做错了。我一直这样做。参见例如github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
  • 不得不手动从情节提要中删除它:customModule="xxxx" customModuleProvider="target"即使一切都在所有目标中。这只发生在我的一个特定情节提要中:不确定是什么让它特别。
【解决方案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,谁知道...)

【讨论】:

  • 第二个答案对我有用。现在我可以用 iOS8 模拟器测试了
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 2019-04-20
  • 2014-12-19
  • 2013-03-14
  • 1970-01-01
  • 2016-06-10
  • 2013-08-09
相关资源
最近更新 更多