UIAppearance会覆盖UILabel上的自定义textColor

时间:2018-11-30 17:50:53

标签: swift uilabel interface-builder uiappearance ibdesignable

我使用以下方法在应用程序委托中设置UILabel外观:

UILabel.appearance().textColor = UIColor.white

我还有一个自定义的UIView子类,其中包含一个UILabel以及一些其他元素(此处省略):

@IBDesignable
class CustomView: UIView {
    private let descriptionLabel = HCLabel()

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

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }

    private func setup() {
        self.descriptionLabel.textColor = UIColor.black

        // ... other things not related to descriptionLabel
    }
}

如果我在情节提要中实例化CustomView,则一切正常。但是,如果我在代码中实例化它,则descriptionLabel是白色(外观颜色),而不是黑色(我设置的颜色)。这里发生了什么?据我了解,如果我设置自定义颜色,将不会使用外观颜色。

1 个答案:

答案 0 :(得分:2)

您遇到的只是与UIAppearance代理将其设置应用于新UIView的确切时间有关。我们什么时候可以假设这样做?它不可能在之前 init之前完成,因为init是UIView生命中首先发生的事情。因此,事件的顺序是这样的:

override init(frame: CGRect) {
    super.init(frame: frame)
    setup() // black
}
// and some time later, UIAppearance proxy comes along and sets it to white

因此,您的目标是在标签生命周期的早期(当然是在用户没有机会看到标签之前)调用setup,而不是在UIAppearance的早期就调用它们。代理行为以后。让我们将调用移至setup到标签寿命的较晚时间:

// some time earlier, UIAppearance proxy sets it to white
override func didMoveToSuperview() {
    setup() // black
}

现在我们要在之后行动,外观代理有机会行动,因此您的设置是最后一次可以使用的设置,并且他们赢得了胜利。

我们仍然不了解如何,我们可以将呼叫移至setup,并且在遵守外观代理设置之后仍会出现。如果有时间,您可能想尝试一下。例如,willMoveToSuperview早一些;如果您在此处致电setup(而不在didMoveToSuperview致电),是否可行?玩耍找出答案!