You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为NSMutableAttributedString添加粗体并保留其他字体特征?

问题核心原因

你当前的实现直接使用全局统一的normalFont生成粗体字体,覆盖选中范围的.font属性,会丢失选中范围内每段文本原本的字体特征(比如斜体、自定义字号、特殊字族)。下划线属于独立的富文本属性,本身不会被字体修改操作影响,问题根源是字体替换逻辑没有基于原有字体做增量修改。

正确实现逻辑
  • 不直接使用全局预设字体生成粗体,逐段读取选中范围内每段文本已有的字体属性
  • 基于每段原有字体的特征集合,追加.traitBold粗体特征,不覆盖已有的斜体等其他特征
  • 用追加特征后的字体描述生成新字体,仅更新对应片段的字体属性,保留所有原有字体相关配置
可直接使用的修正代码
let text = NSMutableAttributedString(attributedString: textView.attributedText)
let selectedRange = textView.selectedRange

text.enumerateAttribute(.font, in: selectedRange, options: []) { fontAttr, range, _ in
    // 优先取当前段原有字体,无字体属性时降级到全局默认字体
    let originalFont = fontAttr as? UIFont ?? AppearanceManager.shared.font ?? .systemFont(ofSize: 14)
    // 在原有字体特征基础上追加粗体,不覆盖斜体等已有特征
    var traits = originalFont.fontDescriptor.symbolicTraits
    traits.formUnion(.traitBold)
    
    guard let boldFontDescriptor = originalFont.fontDescriptor.withSymbolicTraits(traits) else { return }
    let targetBoldFont = UIFont(descriptor: boldFontDescriptor, size: originalFont.pointSize)
    
    text.addAttribute(.font, value: targetBoldFont, range: range)
}

textView.attributedText = text
补充说明
  • 下划线、文字颜色、删除线、字间距等非字体类富文本属性不会被上述逻辑修改,会完整保留
  • 原有字体的斜体特征、自定义字族、局部不同字号等字体相关配置都会被保留,仅额外增加粗体效果
  • 如果需要实现取消粗体的功能,仅需将代码中traits.formUnion(.traitBold)替换为traits.remove(.traitBold)即可,逻辑通用
  • 禁止直接给整个选中范围设置统一字体值,否则会抹掉选区内所有局部字体差异

内容的提问来源于stack exchange,提问作者Michael Sebsbe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:57:14