如何使用IBInspectable控制子视图的属性?

时间:2018-11-10 10:40:44

标签: ios swift uiview

我正在编写一个具有两个标签作为子视图的自定义视图-titleLabelsubtitleLabel

我添加了两个@IBInspectable属性,分别称为titleTextsubtitleText,以便可以在情节提要中轻松设置标签的文本。

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属性之前可以调用的方法是什么,我可以重写该方法来初始化子视图?

1 个答案:

答案 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()

您可以将标签添加为子视图,以后再更新框架。