SwiftUI中无法为NSAttributedString应用系统默认SF字体问题
解决SwiftUI中HTML转NSAttributedString后的字体与颜色自定义问题
问题背景
将HTML转为NSAttributedString后默认使用TimesNewRoman 12pt字体,需要实现三个需求:
- 替换为系统默认字体
- 正文字号调整为14pt
- 设置自定义文本颜色
之前尝试通过字体描述符匹配系统字体失败,核心原因是系统字体(San Francisco系列)的描述符结构特殊,matchingFontDescriptors无法正确匹配指定的家族名称。
可靠解决方案
直接基于原字体的权重生成对应系统字体,同时统一设置文本颜色,无需依赖字体描述符匹配:
let htmlContent = "<p>示例HTML内容</p><h3>标题示例</h3>" let data = Data(htmlContent.utf8) var formattedAttributedString: NSAttributedString? if let rawAttrStr = try? NSMutableAttributedString( data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil ) { // 1. 遍历替换所有字体:保留原权重,调整字号比例 rawAttrStr.enumerateAttribute( .font, in: NSRange(location: 0, length: rawAttrStr.length), options: [] ) { value, range, _ in guard let currentFont = value as? UIFont else { return } // 按原字号的14/12比例放大,保留原字体权重(如加粗、斜体) let scaledSize = currentFont.pointSize * (14.0 / 12.0) let systemFont = UIFont.systemFont(ofSize: scaledSize, weight: currentFont.weight) rawAttrStr.addAttribute(.font, value: systemFont, range: range) } // 2. 设置全局自定义文本颜色(若需局部颜色可单独针对range调整) let customColor = UIColor.darkGray // 替换为你的自定义颜色 rawAttrStr.addAttribute( .foregroundColor, value: customColor, range: NSRange(location: 0, length: rawAttrStr.length) ) formattedAttributedString = rawAttrStr } // SwiftUI中使用 Text(formattedAttributedString ?? NSAttributedString(string: "加载失败")) .environment(\.layoutDirection, .leftToRight) // 避免RTL布局问题
关键说明
- 字体替换逻辑:直接用
UIFont.systemFont生成对应权重的系统字体,既避免了字体描述符匹配的坑,还能保留原HTML中的字体样式(比如标题的加粗会自动对应系统字体的bold权重)。 - SwiftUI修饰符限制:NSAttributedString的内置属性优先级高于SwiftUI的
font/foregroundColor修饰符,所以必须修改NSAttributedString内部的属性才能生效。 - 布局方向处理:添加
environment(\.layoutDirection, .leftToRight)避免HTML转换后可能出现的布局方向异常。
内容的提问来源于stack exchange,提问作者CalebK
相关产品推荐
相关产品推荐

