从 nib 加载自定义 UIView 会导致无限循环或抛出 nil 异常

Posted

技术标签:

【中文标题】从 nib 加载自定义 UIView 会导致无限循环或抛出 nil 异常【英文标题】:loading a custom UIView from a nib either causes an infinite loop or throws a nil exception 【发布时间】:2015-12-18 17:49:40 【问题描述】:

我创建了一个自定义视图 (ImageAndToolBarContainerView),其中包含我想加载到我的应用程序中的多个 UIViewController 中的相应 XIB 文件。

我一直在寻找有关如何执行此操作的适当教程,但我遇到的几乎每一个都太旧或导致重大异常。

当我尝试通过故事板/NIB 加载它时,(我在故事板上的 UIViewController 中创建了一个视图,并将“Class”属性设置为 ImageAndToolBarContainerView。我设置了出口,包括视图,但在调用类时它们似乎都没有加载,我收到错误:

致命错误:在展开可选值时意外发现 nil

当我尝试访问视图时:

required init?(coder aDecoder: NSCoder)

    super.init(coder: aDecoder)
    //setup()
    self.view.frame = self.bounds
    self.addSubview(view)

然后,我尝试使用以下代码来加载 NIB(通过取消注释上面的 setup() 函数。设置代码是这样的:

func setup()

    self.loadViewFromNIB()
    self.view.frame = self.bounds
    self.addSubview(view)


func loadViewFromNIB() -> UIView

    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: "ImageAndToolBarContainer", bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view

这当然会导致无限循环。

我还声明了以下函数:

override func awakeFromNib()

    super.awakeFromNib()
    self.view.frame = self.bounds
    self.addSubview(view)

我在这里缺少什么?我哪里做错了?是否有关于如何正确执行此操作的权威教程?

【问题讨论】:

纯 FWIW。这些天你真的应该只使用容器视图。它有点像 ios 编程的“房间里的大象”。 everything 现在应该只是一个容器视图。这非常容易。苹果这样做正是为了消除你提到的所有问题。长教程***.com/a/23403979/294884 您的自定义视图的 .nib 的文件所有者是谁?你是如何创建你的视图控制器的?它们是来自 Storyboard 还是另一个 .nib? 好像您在ViewClass 字段中设置ImageAndToolBarContainerView,而不是在File's Owner 中设置它。 谢谢你,乔,我会复习的。在文件所有权方面,nib 的所有者是 ImageAndToolBarContainerView 类。视图控制器是在情节提要中创建的。 ImageAndToolBarContainerView 也设置在 File Owner 中,而不是在 View 的类中 你查到这件事的底部了吗?我似乎遇到了类似的问题! 【参考方案1】:

无限循环可能是因为您设置了文件的所有者并将视图的类子类化为视图的类名。

【讨论】:

【参考方案2】:

对于遇到此问题的任何人,如果您为表格或集合视图注册一个 Nib,您就是在告诉父视图在需要出列单元格时去加载一个名为“x”的 nib。

通常使用 Nib 代码,您需要一个方法去加载实际的 XML,使您的布局将其绑定到 Nib 类,但是当您注册可重用视图时,您的注册意味着父视图负责这样做。它实际上会为您加载一个 XML 文件,并在您转换它时尝试将其绑定到一个类。通过在其中添加另一个 loadViewFromNIB 调用将导致发生无限循环。

您需要做的就是将单元格 Nib 的类设置为您的自定义类,注册它,它会使用可重复使用的单元格为您完成剩下的工作 - 从单元格内的任何初始化程序中删除 loadViewFromNIB 方法并添加注册码集合或表视图类。

【讨论】:

以上是关于从 nib 加载自定义 UIView 会导致无限循环或抛出 nil 异常的主要内容,如果未能解决你的问题,请参考以下文章

从 nib 实例化 UIView 导致无限循环问题

如何使用 Swift 从 UITableViewCell 内的 NIB 调整自定义 UIView 的大小?

从 Nib 加载的 UIView,手动调用 autolayout

如何在加载了 nib 文件的 UIView 中调整子视图的大小

Swift 从 Nib 创建自定义视图

iOS 8 中 Nib 加载的子视图的位置不正确