UIAppearance覆盖了UILabel上自定义的textColor

3

我在我的应用程序代理中使用以下代码设置了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
    }
}

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

你确定已经验证了 setup 是否被调用了吗? - rmaddy
是的,它被称为并且UILabel的颜色已经改变,但显然在稍后的某个地方又被改回去了。 - BlackWolf
我编辑了问题以修复一个错误 - CustomView 不是使用故事板实例化的,而是通过编程方式实现的。 - BlackWolf
在实现didMoveToSuperview方法中调用setup。 - matt
这确实有效,但你能解释为什么吗?我知道UIAppearance属性在视图移动到superview/window时设置,但我也以为设置自定义值会阻止这种情况发生。我不认为如果项目中的另一个开发人员在6个月后以类似的方式使用UILabel,他/她将能够弄清楚为什么设置textColor根本没有效果... - BlackWolf
我觉得这很明显,但可能只是我个人的看法。我在下面的回答中提供了更多细节。 - matt
1个回答

5
您所遇到的问题只是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”中),这是否有效?尝试并找出答案!

谢谢您的回复。虽然如此,我仍然觉得我不太明白应该如何使用UIAppearance - 如果使用它意味着我不能再在界面构建器中自定义UILabel,而且每次使用它时都需要绕过一些麻烦的代码,这对我来说似乎是一个相当有缺陷的设计。我想我将无法使用它了。不过,您的答案有效且解释得很清楚,所以我会接受它的;-) - BlackWolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接