在我的项目中,我尝试从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调用是在无限循环中调用的。我的自定义视图
中的调用层次结构如下所示nib.instantiate调用init编码器,循环变为无限期
有关如何解决此问题的任何建议?
答案 0 :(得分:3)
您的setupView()
(在init(coder:)
中执行)会再次加载nib,再次触发init with coder
,从而导致无限递归。
不要在init(coder:)
内实例化nib。如果要在加载后配置视图,请在awakeFromNib
方法中执行此操作。
答案 1 :(得分:2)
如果您的xib文件包含您的视图实例,然后它被加载,它将调用init(编码器:),然后再次加载xib文件,循环将重新启动。我要么从xib文件中删除你的视图实例,要么不要在init(编码器:)中调用setupView()
答案 2 :(得分:1)
答案 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建立到您的代码文件中。