从iOS 15开始,Swift提供了AttributedString结构体,该结构体包含字符串的文本沿着样式属性。问题:给定一个现有的AttributedString,并且假设(为了简单起见)属性由一个样式运行组成,你如何更改 * 只是字符串的部分 * AttributedString?
下面是一个典型的用例-UIButton。假设我有一个基于配置的按钮,带有属性标题:
let button = UIButton(configuration: .plain())
let font = UIFont(name: "Georgia", size: 16)
button.configuration?.attributedTitle = AttributedString(
"Hello", attributes: AttributeContainer.font(font!)
)
字符串
如果我稍后将配置的标题设置为不同的标题,则属性信息将丢失。举例来说:
button.configuration?.title = "Goodbye"
// Button title is no longer in Georgia font!
型
显然,我在这里要做的是替换属性字符串标题的 text,而不干扰它的 attributes。但是Swift的AttributedString似乎并没有提供这样的方法。
所以,正如我一开始就问的:正确的方法是什么?
1条答案
按热度按时间ktecyv1j1#
更改AttributedString的文本非常棘手。您必须替换属性化字符串的字符视图的内容-它的
characters
属性。更难的是,你不能简单地通过分配另一个字符串来实现这一点!以我们的按钮为例,这不会编译:
字符串
从简单的字符串派生字符视图也不够。这也不会编译:
型
这是因为简单字符串的单独字符视图不再存在;你还在尝试将字符串赋值到字符视图中,我们已经知道你不能这样做。
相反,您可以直接从String创建AttributedString.CharacterView,并将 that 赋值给目标属性字符串的
characters
属性。Swift推断类型在这里有很大的帮助:型
这将替换按钮的标题,而不会干扰按钮标题的样式属性。
按钮详情
替换按钮的标题是一件非常有用的事情,所以我在UIButton上做了一个小的实用扩展,涵盖了所有的情况-一个按钮不是基于配置的,一个按钮是基于配置的但没有属性标题,一个按钮是基于配置的但有属性标题:
型
按钮更多
在基于配置的按钮的情况下,人们可能会问到,为什么要使用
attributedTitle
?为什么不在按钮配置的buttonConfig.titleTextAttributesTransformer
中设置字体?答案是,对于需要动态响应用户更改其文本大小偏好的现实字体,这不起作用。为了理解我的意思,试试这个例子:
型
您将看到,尽管按钮标题最初以正确的字体显示,尽管字体在设置按钮的配置标题后仍然存在,但字体大小的 * 动态性 * 已经丢失。对于动态大小的字体,您必须将字体设置为属性标题的一部分。
事实上,这是最终激发了我最初的问题的用例,因此也是这个答案。