HTML渲染NSAttributedString后,如何保留指定颜色并适配明暗模式
解决HTML渲染时保留指定颜色并切换其余文本明暗模式颜色的问题
直接全局设置foregroundColor会覆盖HTML中已定义的颜色样式,正确的做法是仅为未指定颜色的文本区间设置明暗模式对应的颜色,可以通过遍历属性字符串的区间来实现:
修改你的String扩展中的htmlToAttributedString方法如下:
extension String { var htmlToAttributedString: NSAttributedString? { guard let data = data(using: .utf8) else { return nil } do { let style = NSMutableParagraphStyle() style.alignment = NSTextAlignment.center let str = try NSMutableAttributedString( data: data, options: [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ], documentAttributes: nil ) // 先设置全局段落样式 str.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: str.length)) // 根据明暗模式获取目标颜色 let traitCollection = UITraitCollection.current let defaultTextColor = traitCollection.userInterfaceStyle == .dark ? UIColor.white : UIColor.black // 遍历所有属性区间,为未指定颜色的文本设置默认颜色 str.enumerateAttributes(in: NSRange(location: 0, length: str.length), options: []) { attributes, range, _ in if attributes[.foregroundColor] == nil { str.addAttribute(.foregroundColor, value: defaultTextColor, range: range) } } return str } catch { return nil } } var htmlToString: String { return htmlToAttributedString?.string ?? "" } }
关键逻辑说明:
- 遍历属性区间:通过
enumerateAttributes方法逐个检查属性字符串中的每个连续属性区间,该方法会自动按属性变化分割文本段。 - 判断颜色属性:对每个区间,检查是否已存在
.foregroundColor属性——HTML中通过<span style="color:...">定义的文本会自带这个属性,直接跳过这些区间。 - 设置明暗模式颜色:对没有颜色属性的区间,根据当前的
userInterfaceStyle(明暗模式)设置对应的默认文本颜色。 - 保留原有样式:所有HTML中已定义的样式(比如你示例中的橙色文本)都会被完整保留,不会被覆盖。
内容的提问来源于stack exchange,提问作者Hitesh Sapra
相关产品推荐
相关产品推荐

