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

Posted

技术标签:

【中文标题】从 nib 实例化 UIView 导致无限循环问题【英文标题】:Instantiate UIView from nib causes infinite loop issue 【发布时间】:2018-03-06 09:06:16 【问题描述】:

我正在尝试使用我创建的自定义视图。

我使用 nib 的实例化,但它会导致无限循环,我不确定如何修复。有什么想法吗?

这是运行结果的图片:

这是导致问题的代码:

// MARK:  - Init & Setup
// Needed for IBDesignable



override init(frame: CGRect) 
    super.init(frame: frame)
    setup()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    setup()


func setup()
    view = loadViewFromNib()
    view.frame = bounds
    view.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))
    addSubview(view)


func loadViewFromNib() -> UIView
    let bundle = Bundle(for:type(of: self))
    let nib = UINib(nibName: "LoginView", bundle: bundle)         // TEST: changin bundle from bundle-> nil

    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
    return view

编辑:这是连接的图像

谢谢:)

【问题讨论】:

请添加您如何将 LoginView.xib 连接到 LoginView.swift 的图片。可能会有一些问题。 【参考方案1】:

快速回答: 由于 Xib 中的***视图将其 custom class 设置为 YourCustomeView,因此 xib 加载过程 loadViewFromNib 将再次调用您的 initWithCoder 方法⛔️?♽。

快速修复: 在Xib中,不要将视图的自定义类设置为YourCustomeView,而是将YourCustomeView设置为Xib的The File Owner

更多信息 https://medium.com/@anandin02/loading-custom-views-in-ios-the-right-way-bedfc06a4fbd

【讨论】:

【参考方案2】:

从您的示例中不清楚(请下次提供整个文件,而不仅仅是其中的一部分),但看起来您正在尝试从其自身实例化 LoginView。

init() -> setup() -> loadViewFromNib() -> init() -> ...

问题是instantiate 将调用LoginView 的init() 方法,该方法将再次调用loadViewFromNib()。我希望你现在能看到问题。

你想用 loadViewFromNib 做什么?

编辑:在第二张图片的右上角有一个“自定义类”部分。在那里,在“类”字段中,您必须提供控制器的名称(LoginViewController 或类似名称)。通过这种方式,您可以连接视图和控制器,并且不需要导致问题的自定义 loadViewFromNib 方法。

【讨论】:

是的,没错。我无法让它可见。我在情节提要或运行应用程序时看不到自定义控制器【参考方案3】:

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

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

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

【讨论】:

以上是关于从 nib 实例化 UIView 导致无限循环问题的主要内容,如果未能解决你的问题,请参考以下文章

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

如何从 ViewController 中的 xib (nib) 实例化 UIView / UITableView

无法从 nib 实例化 UIView。 “警告:无法加载任何 Objective-C 类信息”

如何在不使用 Nib 的情况下实例化和调用 UIView 子类

从 XIB 问题动态实例化自定义 UIView(此代码有啥问题)?

更改使用 loadNibNamed 实例化的类