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>
使用说明
- 调用
yourHTMLString.convertToAttributedString()获取处理后的富文本 - 将结果直接赋值给
UITextView.attributedText - 可调整
indentPerLevel的数值,适配不同的界面布局需求
内容的提问来源于stack exchange,提问作者MeetMistry15
相关产品推荐
相关产品推荐

