问题:为什么UILabel在从XIB以编程方式创建UIView后,在init(代码附加)中没有? (请参阅下面的代码)这是行label1.text = "TBC - It was updated"
抛出错误
背景:我想以编程方式创建多个自定义视图,在这种情况下需要多个GCDateView。我想使用XIB
文件来布局自定义视图和关联类,以编程方式完成自定义,因此我在这里有一个GCDateView.swift和一个GCDateView.xib文件。
除了:作为第二个问题,我注意到我在xib文件中创建的GCDateView视图无法直接分配为主视图(例如,在init结束时我可以不要说self = gcDateViewView
)。也许我需要一个单独的问题。
从父控制器/视图中:
let dv = GCDateView()
GCDateView:
import UIKit
class GCDateView : UIView {
@IBOutlet weak var label1: UILabel!
func commonInit() {
// Programmtically use XIB file
if self.subviews.count == 0 {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "GCDateView", bundle: bundle)
let gcDateViewView : UIView = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
gcDateViewView.frame = self.bounds
gcDateViewView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(gcDateViewView)
}
**label1.text = "TBC - It was updated" // ** ERROR: label1 was Nil ****
}
override init(frame: CGRect) {
NSLog("GCDateView: Init frame")
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
NSLog("GCDateView: Init decoder")
super.init(coder: aDecoder)
commonInit()
}
}
答案 0 :(得分:5)
IBOutlet
个实例未在init?(coder aDecoder: NSCoder)
中初始化
该过程在单独的步骤中完成。
方法awakeFromNib
确保所有IBOutlet
个实例都已初始化:
override func awakeFromNib() {
super.awakeFromNib()
label1.text = "TBC - It was updated" // Won't crash.
}
要解决您的第二个问题(即避免将自我类型的另一个实例添加为自我子视图),我建议创建类方法,通过从xib加载来创建GCDateView
的新实例。
这是更新的代码:
import UIKit
class GCDateView : UIView {
@IBOutlet weak var label1: UILabel!
class func loadFromXIB() -> GCDateView {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "GCDateView", bundle: bundle)
let gcDateView = nib.instantiate(withOwner: self, options: nil)[0] as! GCDateView
gcDateView.frame = self.bounds
gcDateView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
gcDateView.label1.text = "TBC - It was updated"
return gcDateView
}
}
用法:
let dateView = GCDateView.loadFromXIB()