一尘不染

NSAttributedString,更改字体总体,但保留所有其他属性吗?

swift

说我有一个NSMutableAttributedString

在整个字符串中,字符串具有 多种 __格式 组合

这是一个例子:

这个字符串 在iOS中 很难 改变*真的 很烂 *

但是,字体本身不是您想要的字体。

我想要:

对于每个字符,将该字符更改为特定 字体 (例如Avenir)

但,

对于每一个角色, 保持组合其他 这是以前对这个角色的地方归因(粗体,斜体,颜色,等等等等)。

你到底是怎么做到的?


注意:

如果您在整个范围内微不足道地添加属性“ Avenir”:它只是 删除了所有其他属性范围 ,则会丢失所有格式。不幸的是,属性 实际上不是
“加法”的。


阅读 249

收藏
2020-07-07

共1个答案

一尘不染

由于rmaddy的答案对我f.fontDescriptor.withFace(font.fontName)不起作用(不保留粗体之类的特征),因此这是Swift
4的更新版本,其中还包括颜色更新:

extension NSMutableAttributedString {
    func setFontFace(font: UIFont, color: UIColor? = nil) {
        beginEditing()
        self.enumerateAttribute(
            .font, 
            in: NSRange(location: 0, length: self.length)
        ) { (value, range, stop) in

            if let f = value as? UIFont, 
              let newFontDescriptor = f.fontDescriptor
                .withFamily(font.familyName)
                .withSymbolicTraits(f.fontDescriptor.symbolicTraits) {

                let newFont = UIFont(
                    descriptor: newFontDescriptor, 
                    size: font.pointSize
                )
                removeAttribute(.font, range: range)
                addAttribute(.font, value: newFont, range: range)
                if let color = color {
                    removeAttribute(
                        .foregroundColor, 
                        range: range
                    )
                    addAttribute(
                        .foregroundColor, 
                        value: color, 
                        range: range
                    )
                }
            }
        }
        endEditing()
    }
}

笔记

的问题f.fontDescriptor.withFace(font.fontName)是,它消除了象征性的特质一样italicbold或者compressed,因为它会因为某些原因忽略那些与字型的默认特征。为什么这是如此令我难以理解,甚至可能是苹果的疏忽。或“不是错误,而是功能”,因为我们免费获得了新字体的特征。

因此,我们要做的是创建一个字体描述符,该描述符具有原始字体的字体描述符中的符号特征.withSymbolicTraits(f.fontDescriptor.symbolicTraits)。为rmaddy支持我迭代的初始代码。

我已经在生产应用程序中交付了它,我们在其中通过解析HTML字符串NSAttributedString.DocumentType.html,然后通过上述扩展名更改字体和颜色。到目前为止没有问题。

2020-07-07