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

iOS低版本下NSAttributedString解析HTML标签并添加样式的问题

问题描述

我有如下本地化字符串:

"Register and get <b>all</b>
<b>rewards cards</b> of our partners
<b>in one</b> universal <b>card</b>"

其中部分内容需要加粗显示,同时要设置自定义段落样式(行间距、居中对齐、最小行高)。

目前我有两段代码:

  1. 能实现段落样式但无法处理HTML加粗标签:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 1.0
paragraphStyle.alignment = .center
paragraphStyle.minimumLineHeight = 18.0

let attributedString = NSMutableAttributedString(string: descriptionString, attributes: [.font: UIFont.proximaNovaRegularWithSize(size: 15.0),
                                                                                         .paragraphStyle: paragraphStyle])
  1. 能解析HTML标签的方法,但无法和自定义样式结合生效:
func convertFromHTMLString(_ input: String?) -> NSMutableAttributedString? {
    guard let input = input else { return nil }

    guard let data = input.data(using: String.Encoding.unicode, allowLossyConversion: true) else { return nil  }
    return try? NSMutableAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html], documentAttributes: nil)
}

我尝试通过defaultAttributes同时设置字体和段落样式,但并未生效,字体和自定义段落样式都没有被应用,效果不符合预期。

注:App需要兼容iOS 15以下版本,无法使用Markdown语法。

解决方案

问题出在HTML解析生成富文本时,defaultAttributes优先级较低,解析器会用系统默认样式覆盖自定义设置。正确做法是先解析HTML得到带加粗格式的富文本,再遍历统一添加全局样式,同时保留加粗部分的特殊字体。

具体实现代码

func convertHTMLToStyledAttributedString(_ input: String?) -> NSMutableAttributedString? {
    guard let input = input else { return nil }
    
    // 1. 解析HTML标签,生成带加粗格式的基础富文本
    guard let data = input.data(using: .utf8, allowLossyConversion: true) else { return nil }
    let htmlOptions: [NSAttributedString.DocumentReadingOptionKey: Any] = [
        .documentType: NSAttributedString.DocumentType.html,
        .characterEncoding: String.Encoding.utf8.rawValue
    ]
    guard let attributedString = try? NSMutableAttributedString(data: data, options: htmlOptions, documentAttributes: nil) else { return nil }
    
    // 2. 定义全局样式参数
    let baseFont = UIFont.proximaNovaRegularWithSize(size: 15.0)
    let boldFont = UIFont.proximaNovaBoldWithSize(size: 15.0) // 需确保项目中有对应的加粗字体
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.alignment = .center
    paragraphStyle.minimumLineHeight = 18.0
    
    // 3. 遍历富文本,统一设置样式并保留加粗特性
    attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: []) { attributes, range, _ in
        var newAttributes = attributes
        
        // 强制设置自定义段落样式
        newAttributes[.paragraphStyle] = paragraphStyle
        
        // 根据原有字体特性替换为自定义字体:加粗文本用自定义加粗字体,其余用常规字体
        if let existingFont = attributes[.font] as? UIFont, existingFont.fontDescriptor.symbolicTraits.contains(.traitBold) {
            newAttributes[.font] = boldFont
        } else {
            newAttributes[.font] = baseFont
        }
        
        attributedString.setAttributes(newAttributes, range: range)
    }
    
    return attributedString
}

关键说明

  1. 先解析后样式:HTML解析会生成带默认格式的富文本,后续遍历修改能确保自定义样式覆盖系统默认值,同时保留<b>标签的加粗效果。
  2. 自定义字体匹配:解析<b>标签后系统会自动添加加粗字体特性,需替换为项目使用的自定义加粗字体,避免显示系统默认加粗样式。
  3. 低版本兼容:该方案不依赖iOS 15+的Markdown API,适配更早的系统版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:24:24