【问题标题】:UIAppearance overwrites custom textColor on UILabelUIAppearance 覆盖 UILabel 上的自定义 textColor
【发布时间】:2019-05-02 21:39:18
【问题描述】:

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

【问题讨论】:

  • 你确认setup确实被调用了吗?
  • 是的,它被调用并且 UILabel 的颜色发生了变化,但显然稍后又被改回了
  • 我编辑了问题以修复错误 - CustomView 没有使用情节提要实例化,而是以编程方式实例化。
  • 实现didMoveToSuperview 并在那里调用设置。
  • 这确实有效,但您能解释一下原因吗?我知道 UIAppearance 属性是在视图移动到超级视图/窗口时设置的,但我也认为设置自定义值会阻止这种情况发生。我不认为该项目的另一个开发人员会在 6 个月后以类似的方式使用 UILabel,他/她将能够弄清楚为什么设置 textColor 根本没有效果......

标签: swift uilabel interface-builder uiappearance ibdesignable


【解决方案1】:

您遇到的只是 UIAppearance 代理将其设置应用于新 UIView 的确切时间问题。我们什么时候可以假设它会这样做? before 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),这行得通吗?玩一玩就知道了!

【讨论】:

  • 感谢您的回复。不过,我仍然认为我不太了解应该如何使用 UIAppearance - 如果使用它意味着我无法在界面构建器中自定义 UILabel ,并且在代码中只能通过每次使用它时跳过箍来自定义,这似乎对我来说就像一个有缺陷的设计。我想那时我将无法使用它。不过,您的答案有效并且解释清楚,所以我会接受它;-)
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 2013-03-12
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多