我正在编写一个具有两个标签作为子视图的自定义视图-titleLabel
和subtitleLabel
。
我添加了两个@IBInspectable
属性,分别称为titleText
和subtitleText
,以便可以在情节提要中轻松设置标签的文本。
class MyView : UIView {
var titleLabel: UILabel!
var subtitleLabel: UILabel!
@IBInspectable
var titleText: String? {
get { return titleLabel.text }
set {
titleLabel.text = newValue
let fontSize = // calculates appropriate font size for the text...
titleLabel.font = font.withSize(fontSize)
}
}
@IBInspectable
var subtitleText: String? {
get { return subtitleLabel.text }
set {
subtitleLabel.text = newValue
let fontSize = // calculates appropriate font size for the text...
subtitleLabel.font = font.withSize(fontSize)
}
}
override func draw(_ rect: CGRect) {
// here I make the view look prettier, irrelevant to the question
}
}
现在,我需要初始化这两个标签,并将它们添加为MyView
的子视图。我以为可以在awakeFromNib
中做到这一点:
override func awakeFromNib() {
titleLabel = UILabel(frame: CGRect(
x: ...,
y: ...,
width: ...,
height: ...))
self.addSubview(titleLabel)
subtitleLabel = UILabel(frame: CGRect(
x: ...,
y: ...,
width: ...,
height: ...))
self.addSubview(subtitleLabel)
}
因此,我在情节提要中添加了MyView
,并使用属性检查器设置了其属性,然后运行了该应用程序。它崩溃了。
显然,IBInspectable
属性是在awakeFromNib
之前设置的,因此标签当时尚未初始化。
这意味着我需要在设置IBInspectable
属性之前调用的方法中初始化标签。
在设置IBInspectable
属性之前可以调用的方法是什么,我可以重写该方法来初始化子视图?
答案 0 :(得分:2)
这可能很明显,但是将这些内容放入其中的正确方法是 initializer 。
// called when initialized from code
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
// called when initialized from storyboard/xib
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
// add subviews
}
此外,在您的特定情况下,没有真正的理由选择可选内容:
let titleLabel: UILabel = UILabel()
您可以将标签添加为子视图,以后再更新框架。