UIAppearance 覆盖 UILabel 上的自定义 textColor

UIAppearance overwrites custom textColor on UILabel

我使用以下方法在我的应用委托中设置 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 是白色(外观颜色),而不是黑色(我设置的颜色)。这里发生了什么?我的理解是,如果我设置自定义颜色,外观颜色将不会被使用。

您遇到的只是 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),那行得通吗?玩一玩就知道了!