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

HTML转AttributedString时如何正确保留上标sup样式

解决方案

你不需要手动遍历AttributedString的属性范围,也不需要引入第三方库,利用系统HTML解析器原生支持内联CSS的特性,在解析前给HTML拼接全局样式即可,所有标签样式会在解析阶段自动应用到对应文本范围,不会出现全量覆盖属性的问题。

问题原因

你当前在HTML解析完成后,给全量文本范围统一加15号系统字体的属性,会直接覆盖解析器自动生成的<sup>上标、<sub>下标签自带的小字号、基线偏移属性,最终导致上标和正文字号一致、行高被撑乱。

实现代码

直接修改formatAttributedString方法,移除解析后全量添加字体、段落属性的逻辑,改为在原始HTML前拼接全局CSS样式:

func formatAttributedString() -> NSMutableAttributedString? {
    // 拼接全局样式,指定正文和特殊标签的显示规则
    let styledHTML = """
    <style>
        body {
            font: -apple-system 15pt;
            line-height: 20pt;
            margin: 0;
            padding: 0;
        }
        sup {
            font-size: 10pt;
            vertical-align: super;
            line-height: 0;
        }
        sub {
            font-size: 10pt;
            vertical-align: sub;
            line-height: 0;
        }
    </style>
    \(self.html)
    """
    
    let data = Data(styledHTML.utf8)
    guard let attributedString = try? NSMutableAttributedString(
        data: data,
        options: [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ],
        documentAttributes: nil
    ) else {
        return nil
    }

    return attributedString
}

配置说明

  • font: -apple-system会自动匹配iOS原生系统字体,彻底解决默认显示Times New Roman字体的问题
  • 正文全局设置15pt字号、20pt行高,和你预期的App正文样式完全一致
  • 单独给<sup>、<sub>标签设置10pt小字号,vertical-align属性会自动触发解析器添加正确的基线偏移,还原原生上标/下标效果
  • 给上标下标设置line-height: 0,避免特殊标签撑大整行行高,保证所有正文行高统一为20pt
  • 如果你的HTML中还有<strong>粗体、<em>斜体等其他标签,也可以直接在style块中添加对应选择器的样式规则,解析时会自动生效。

内容的提问来源于stack exchange,提问作者Joshua Maza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:03:26