使用XIB的CustomView - 在init编码器方法

时间:2017-07-18 12:33:59

标签: ios swift uiview xib

在我的项目中,我尝试从XIB文件创建自定义UIView。我遵循了一些教程,并在下面的代码中加载

import UIKit

class StorePricing: UIView {

    override init(frame: CGRect) {

        super.init(frame: frame)
        self.setupView()
    }

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)
        self.setupView()
    }

    private func setupView() {

        let view = self.loadViewFromXib()

        view.frame = self.bounds
        view.autoresizingMask = [.flexibleHeight, .flexibleWidth]

        self.addSubview(view)
    }

    private func loadViewFromXib() -> UIView {

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView

        return view

    }

}

当我在另一个视图中添加此自定义视图时,我的应用程序崩溃,我注意到init调用是在无限循环中调用的。我的自定义视图

中的调用层次结构如下所示
  1. 致电初始编码员
  2. 调用setupView()
  3. 调用loadViewFromXib()
  4. nib.instantiate调用init编码器,循环变为无限期

    有关如何解决此问题的任何建议?

5 个答案:

答案 0 :(得分:3)

您的setupView()(在init(coder:)中执行)会再次加载nib,再次触发init with coder,从而导致无限递归。

不要在init(coder:)内实例化nib。如果要在加载后配置视图,请在awakeFromNib方法中执行此操作。

答案 1 :(得分:2)

如果您的xib文件包含您的视图实例,然后它被加载,它将调用init(编码器:),然后再次加载xib文件,循环将重新启动。我要么从xib文件中删除你的视图实例,要么不要在init(编码器:)中调用setupView()

答案 2 :(得分:1)

文件的所有者类设置为您的自定义类

enter image description here

答案 3 :(得分:0)

这是因为每当您致电setupView()时,您都会添加子视图。所以每次都会再次发生。因为我所做的你可以在下面看到。希望能帮到你。

class TableBackGroundView: UIView {

  // Here is my common view handled
  var view: UIView!

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

        xibSetup()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        xibSetup()
    }

    func xibSetup() {

        let nib = UINib(nibName: "TableBackGroundView", bundle: nil)
        view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

        // use bounds not frame or it'll be offset
        view.frame = bounds

        // Make the view stretch with containing view
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
    }
}

答案 4 :(得分:0)

如果在.xib文件中,对于新视图(StorePricing),您的自定义类类类型设置为新的自定义类名(StorePricing),则可能获得无限递归。它应该设置为UIView。要了解什么'继续,当nib.instantiate(...)正在读取.xib并遇到视图的自定义类名称时,它会调用required init?(coder aDecoder: NSCoder)来创建它,然后围绕它进行。 将文件所有者自定义类设置为您的自定义类。这将允许您将.xib文件中的Referencing Outlets建立到您的代码文件中。