更改AttributedString的文本非常棘手.您必须替换属性字符串的字符视图的内容-它的characters
属性.要使事情变得更加困难,您不能简单地通过分配另一个字符串来做到这一点!
以我们的按钮为例,这将不会编译:
button.configuration?.attributedTitle?.characters = "Goodbye" // error
仅从简单的字符串派生字符视图也是不够的.这也不能编译:
button.configuration?.attributedTitle?.characters = "Goodbye".characters // error
这是因为简单字符串的单独字符视图不再存在;您仍在try 将字符串分配到字符视图中,而我们已经知道您不能这样做.
相反,您可以直接从您的字符串创建一个AttributedString.CharacterView,并将that赋给目标属性化字符串的characters
属性.Swift 推断打字在这方面帮了大忙:
button.configuration?.attributedTitle?.characters = .init("Goodbye")
这将替换按钮的标题,而不会干扰按钮的标题的样式属性.
有关按钮的更多信息
替换按钮的标题是一件非常有用的事情,我在UIButton上做了一个小的实用程序扩展,涵盖了所有情况-一个不基于配置的按钮,一个基于配置但没有属性标题的按钮,以及一个基于配置并具有属性标题的按钮:
extension UIButton {
func replaceTitle(_ newTitle: String) {
guard configuration != nil else {
setTitle(newTitle, for: .normal)
return
}
guard configuration?.attributedTitle != nil else {
configuration?.title = newTitle
return
}
configuration?.attributedTitle?.characters = .init(newTitle)
}
}
更多关于按钮的信息
对于基于配置的按钮,人们可能会问(也已经问过),为什么要使用attributedTitle
?为什么不在按钮配置的buttonConfig.titleTextAttributesTransformer
中设置字体?
答案是,这不适用于需要动态响应用户更改文本大小首选项的真实字体.要理解我的意思,请try 下面的示例:
let button = UIButton(configuration: .plain())
let font = UIFontMetrics(forTextStyle: .subheadline)
.scaledFont(for: UIFont(name: "Georgia", size: 16)!)
button.configuration?.title = "Hello"
button.configuration?.titleTextAttributesTransformer = .init { container in
container.merging(AttributeContainer.font(font))
}
您将看到,尽管按钮标题最初以正确的字体显示,尽管字体在设置按钮的配置标题后仍然存在,但字体大小的dynamism已经丢失.使用动态大小的字体,您可以将字体设置为属性标题的一部分.
事实上,这就是最终启发了我最初问题的用例,并因此得到了这个答案.