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

NSAttributedString解析HTML项目符号换行无缩进问题求助

解决HTML转富文本后列表项换行无缩进的问题

方法1:预处理HTML添加内联样式

在转换前给接口返回的HTML中的<li>标签批量添加CSS样式,通过padding-left和text-indent组合实现悬挂缩进:

// 接口返回的原始HTML
let rawHTML = """
<p>Welcome blah blah</p>
<ul>
<li>Here's bullet point number one blah blah blahb blah blah</li>
<li>Here's bullet point number two</li>
<li>Bullet point number three is longer and will wrap around but look strange blah blah blah</li>
</ul>
"""
// 给所有<li>标签插入样式
let styledHTML = rawHTML.replacingOccurrences(of: "<li>", with: "<li style=\"padding-left: 24px; text-indent: -12px;\">")
// 转换为富文本
let fixedAttributedText = styledHTML.htmlToAttributedString

这种方式利用HTML原生样式能力,转换后的富文本会自动继承悬挂缩进效果,适配长文本换行场景。

方法2:转换后修改NSAttributedString的段落样式

如果无法修改原始HTML,可以在转换为富文本后,遍历调整列表项的段落属性:

public extension String {
    var htmlToAttributedStringWithFixedIndent: NSAttributedString? {
        guard let baseAttributedString = Data(utf8).htmlToAttributedString else { return nil }
        let mutableString = NSMutableAttributedString(attributedString: baseAttributedString)
        
        mutableString.enumerateAttribute(.paragraphStyle, 
                                         in: NSRange(location: 0, length: mutableString.length),
                                         options: .longestEffectiveRangeNotRequired) { value, range, _ in
            let originalStyle = value as? NSParagraphStyle ?? NSParagraphStyle()
            let newStyle = NSMutableParagraphStyle()
            newStyle.setParagraphStyle(originalStyle)
            
            // 判断当前段落是否为列表项(以默认的•符号开头)
            let paragraphText = (mutableString.string as NSString).substring(with: range)
            if paragraphText.hasPrefix("• ") {
                // 设置悬挂缩进:首行无偏移,后续行缩进20pt
                newStyle.firstLineHeadIndent = 0
                newStyle.headIndent = 20
            }
            
            mutableString.addAttribute(.paragraphStyle, value: newStyle, range: range)
        }
        
        return mutableString
    }
}

使用时直接调用htmlToAttributedStringWithFixedIndent即可得到修复缩进的富文本。

方法3:UI层面调整(UITextView专属)

如果仅在UITextView中展示,可通过调整文本容器的内边距实现快速适配:

let textView = UITextView()
// 整体左内边距20pt,抵消首行偏移量
textView.textContainerInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0)
// 首行左移10pt,形成悬挂效果
textView.textContainer.lineFragmentPadding = -10

这种方式无需修改富文本内容,但属于全局调整,需根据实际展示需求微调数值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:39:52