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

Swift中HTML转NSAttributedString多级项目符号对齐问题求助

解决HTML转NSAttributedString多级列表缩进异常问题

默认HTML转NSAttributedString的方法不会自动处理多级列表的层级缩进,所有列表项缩进一致导致层级结构丢失,以下是具体解决方案:

核心思路

遍历转换后的富文本,通过NSListAttributeName识别每个列表项的层级,根据层级调整段落样式的headIndent和firstLineHeadIndent参数,层级越深,缩进值越大。

修改后的String扩展代码

import UIKit

extension String {
    func convertToAttributedString() -> NSAttributedString? {
        guard let data = self.data(using: .utf8) else { return nil }
        
        let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]
        
        guard var attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else { return nil }
        
        // 处理多级列表缩进
        let mutableAttributedString = NSMutableAttributedString(attributedString: attributedString)
        mutableAttributedString.enumerateAttribute(.list, in: NSRange(location: 0, length: mutableAttributedString.length), options: .longestEffectiveRangeNotRequired) { (value, range, stop) in
            guard let list = value as? NSList else { return }
            
            // 每级缩进20pt(可根据UI需求调整)
            let level = list.level
            let indentPerLevel: CGFloat = 20.0
            let totalIndent = indentPerLevel * CGFloat(level)
            
            // 获取或创建段落样式
            let paragraphStyle = mutableAttributedString.attribute(.paragraphStyle, at: range.location, effectiveRange: nil) as? NSMutableParagraphStyle ?? NSMutableParagraphStyle()
            
            // 设置缩进:首行对应项目符号位置,整体缩进对应文本位置
            paragraphStyle.firstLineHeadIndent = indentPerLevel + totalIndent
            paragraphStyle.headIndent = indentPerLevel * 2 + totalIndent
            
            mutableAttributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: range)
        }
        
        return mutableAttributedString
    }
}

测试用HTML字符串示例

<ul>
    <li>一级列表项1</li>
    <li>一级列表项2
        <ul>
            <li>二级列表项1</li>
            <li>二级列表项2
                <ul>
                    <li>三级列表项1</li>
                    <li>三级列表项2</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>一级列表项3</li>
</ul>

使用说明

  1. 调用yourHTMLString.convertToAttributedString()获取处理后的富文本
  2. 将结果直接赋值给UITextView.attributedText
  3. 可调整indentPerLevel的数值,适配不同的界面布局需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:50:21