如果我在iOS8模拟器上运行应用程序,则不会初始化来自xib的IBOutlets

时间:2015-09-17 14:07:42

标签: ios interface-builder ios-simulator swift2

我使用XCode 7 GM(基础SDK - iOS9)构建了一个应用程序。如果我在iOS 9模拟器上运行它,它会完美运行但如果我尝试在iOS8上运行它,它会在这里失败:

@IBOutlet weak var collectionView: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.title = NSLocalizedString("Home", comment: "Home")
    collectionView.registerNib(UINib(nibName: "PTHomeCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PTHomeCollectionViewCell")
}

有错误

  

致命错误:在解包可选值时意外发现nil

因为collectionView是零: enter image description here

当然我已经加倍检查IB中的连接已建立: enter image description here

有人可以告诉我为什么collectionView在这里没有?

3 个答案:

答案 0 :(得分:3)

我能够通过添加

解决此问题
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    let name = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
    super.init(nibName: nibNameOrNil ?? name, bundle: nibBundleOrNil)
}

到视图控制器类。但为什么它这样工作?还有其他方法可以解决这个问题吗?

<强>更新: 它是一个Swift视图控制器功能,非常类似于一个bug。查看thisCan't Load UIViewController XIB file in Storyboard in Swift

它已在iOS 9.4中修复,但如果您需要iOS 8及更早版本的支持,则仍需要使用变通方法。

答案 1 :(得分:1)

Matt Neuburg的书“编程iOS 8 ”中突出显示了这个问题。发生这种情况是因为iOS 8要求xib名称以模块名称为前缀,在这种情况下,模块名称与项目名称相同。例如,如果项目MyViewController中有MyProject,则可能会找到名为MyProject.MyViewController.xib的xib。要解决此问题,请在视图控制器中覆盖nibName

override var nibName: String? { 
    return "\(self.dynamicType)"
}

答案 2 :(得分:0)

您如何实例化视图控制器?

在访问viewController = MyViewController()时,通过IBOutlets进行实例化会在iOS8.x中崩溃(虽然它在iOS9.3中运行正常,可能在iOS9.x中运行)

使用viewController = MyViewController(nibName: "MyViewController", bundle: nil)实例化视图控制器无论iOS版本如何都应该有效。

请参阅此其他帖子以供参考:All my IBOutlet are nil in viewDidLoad