SwiftUI 2.0基于NSRegularExpression实现星号文本加粗的异常问题排查
问题原因及修复方案
1. 紧邻文本出现多余空格的原因
- 核心逻辑缺陷:
RichText视图的shouldAddSpace方法无差别对所有非末尾元素追加空格,完全不考虑原文本中两个元素是否紧贴,比如*des* Mann*es*拆分出的Mann和es两个元素会被强制插入空格,产生Mann es的错误效果。 - 解析逻辑错误:
parseRichTextElements方法中对非匹配文本统一按空格拆分,丢失了原文本的空格位置信息,后续统一补空格的逻辑无法适配所有排版场景。 - 多余trim操作:
TextGroup初始化时调用trimmingCharacters(in: .whitespacesAndNewlines)会误删元素首尾的有效空格,进一步打乱原有排版。
2. JSON中\n换行符不生效的原因
- 换行符被提前清理:
TextGroup初始化的trim操作会直接删除所有换行符,解析逻辑中过滤空串、按空格拆分的操作也会把\n作为空白字符丢弃,无法保留到渲染环节。 - SwiftUI的Text默认支持
\n渲染,只需要保证换行符没有被提前删除即可正常生效。
核心修复方案
步骤1:修改TextGroup初始化逻辑,移除不必要的trim操作
init(content: String, isBold: Bool) { var content = content if isBold { content = content.replacingOccurrences(of: "*", with: "") } self.content = content self.isBold = isBold }
步骤2:移除RichText强制追加空格的逻辑
private func text(for element: TextGroup) -> Text { if element.isBold { return Text(element.content) .fontWeight(.bold) } else { return Text(element.content) } } // 可直接删除无用的shouldAddSpace方法
步骤3:修改解析逻辑,保留原文本的空格、换行信息
删除非匹配段按空格拆分的逻辑,直接将非匹配文本作为整体元素添加:
// 替换第一段非匹配文本的处理逻辑 let firstContent = String(self[firstRange]) if !firstContent.isEmpty { elements.append(TextGroup(content: firstContent, isBold: false)) } // 替换匹配段之间的非匹配文本处理逻辑 let range = matchingRange.upperBound..<endLocation let middleContent = String(self[range]) if !middleContent.isEmpty { elements.append(TextGroup(content: middleContent, isBold: false)) }
内容的提问来源于stack exchange,提问作者Ufuk Köşker
相关产品推荐
相关产品推荐

