如何使 UIAppearance 代理适用于以编程方式创建的视图?

Posted

技术标签:

【中文标题】如何使 UIAppearance 代理适用于以编程方式创建的视图?【英文标题】:How to make UIAppearance proxies apply to programmatically created views? 【发布时间】:2017-10-05 18:21:21 【问题描述】:

我正在尝试使用 UIAppearance 为我的应用创建主题。

假设我希望我的 UILabel 的所有文本都是橙色的。我写道:

UILabel.appearance(whenContainedInInstancesOf: [UIView.self]).textColor = .orange

但我意识到:

这适用于通过 Interface Builder 创建的每个 UILabel。 这不适用于以编程方式创建的任何UILabel。它们默认显示为黑色

知道如何强制以编程方式创建的实例也变为橙色吗?

PS:我也试过:UILabel.appearance().textColor = .green 这不是我想要的,但它也不起作用。

【问题讨论】:

实际上UILabel.appearance().textColor 应该可以工作。什么时候调用这个方法? 【参考方案1】:

经过一番搜索……

显然,在 Interface Builder 中创建的 UI 元素(例如标签).appearance() 设置影响这一事实并非有意为之,而且可能并不可靠.

事实上,文档似乎相当混乱和误导。

要支持外观自定义,类必须符合 UIAppearanceContainer 协议,并且相关的访问器方法必须用 UI_APPEARANCE_SELECTOR 标记。

唯一采用UIAppearance协议的类是

UIBarItem UIView

唯一采用UIAppearanceContainer协议的类是

UIPopoverController UIPresentationController UIView UIViewController

所以...最好的选择可能是对您的标签进行子分类。

【讨论】:

【参考方案2】:

相关答案可以在这里找到:How to default UILabel Font and Size using Swift

从那个链接: "UIAppearance 只允许您在 Objective-C 头文件中设置带有 UI_APPEARANCE_SELECTOR 标记的属性。由于 UILabel 没有此类属性,因此无法使用 UIAppearance 设置样式"

也来自:https://developer.apple.com/documentation/uikit/uiappearance

“当视图进入窗口时,ios 应用外观更改,它不会更改已经在窗口中的视图的外观。要更改当前在窗口中的视图的外观,请从视图中删除视图层次结构,然后放回去。”

也来自这里:trouble with UIAppearance and UIButton subclassing

“它以这种方式工作的原因是因为外观属性是在视图添加到视图层次结构时应用的,而 nib 定义的属性是在视图添加到视图层次结构之前应用的。”

在以编程方式将该视图控制器添加到层次结构之前,我尝试在新类视图控制器的实例中设置标签的外观,但没有运气。

【讨论】:

以上是关于如何使 UIAppearance 代理适用于以编程方式创建的视图?的主要内容,如果未能解决你的问题,请参考以下文章

检测自定义按钮的 UIAppearance 代理中的更改

使用 UIAppearance 代理设置 UILabel 样式

限制 UIAppearance 代理范围

编译时间之间的 UIAppearance 代理缓存外观?

UIAppearance 代理规则何时应用于新的视图控制器?

使用 UIAppearance 代理自定义字体时,MFMailComposeViewController 不起作用