如何使用SwiftUI实现文本中指定标记词汇的高亮展示
SwiftUI 自定义包裹标记文本高亮实现方案
实现思路
- 用正则表达式匹配所有被
###和$$$包裹的文本段,拆分原始字符串为「普通文本」和「待高亮文本」两类分段 - 利用SwiftUI中
Text支持直接拼接的特性,分别给不同类型的分段设置高亮样式后拼接为完整文本
完整实现代码
首先是字符串解析工具方法:
// 文本分段模型 private struct TextSegment: Identifiable { let id = UUID() let content: String let isHighlight: Bool } /// 解析带### $$$标记的字符串为文本分段 private func parseHighlightString(_ original: String) -> [TextSegment] { var segments: [TextSegment] = [] // 非贪婪匹配正则,捕获###和$$$中间的内容 let pattern = "###(.*?)\\$\\$\\$" guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { return [TextSegment(content: original, isHighlight: false)] } let fullRange = NSRange(original.startIndex..., in: original) let matches = regex.matches(in: original, range: fullRange) var lastEnd = original.startIndex for match in matches { // 匹配到的完整标记范围(包含###和$$$) guard let fullMatchRange = Range(match.range(at: 0), in: original), let highlightContentRange = Range(match.range(at: 1), in: original) else { continue } // 拼接上一段普通文本 let prefixRange = lastEnd..<fullMatchRange.lowerBound if !prefixRange.isEmpty { segments.append(TextSegment(content: String(original[prefixRange]), isHighlight: false)) } // 拼接高亮文本 segments.append(TextSegment(content: String(original[highlightContentRange]), isHighlight: true)) lastEnd = fullMatchRange.upperBound } // 拼接最后剩余的普通文本 if lastEnd < original.endIndex { segments.append(TextSegment(content: String(original[lastEnd...]), isHighlight: false)) } return segments }
然后是View层的调用实现:
struct HighlightDemoView: View { private let testStr = "When I was ###young$$$, I thought ###time$$$ was money" var body: some View { VStack { buildHighlightText() .font(.system(size: 16)) } .padding() } /// 拼接生成最终高亮文本 private func buildHighlightText() -> Text { let segments = parseHighlightString(testStr) var finalText = Text("") for segment in segments { if segment.isHighlight { // 可自定义高亮样式:文字颜色、背景色、字重等 finalText = finalText + Text(segment.content) .foregroundColor(.white) .background(.orange) .fontWeight(.medium) } else { finalText = finalText + Text(segment.content) .foregroundColor(.black) } } return finalText } }
自定义说明
- 如需调整高亮效果,修改
segment.isHighlight判断分支内的样式修饰符即可,比如更换高亮背景色、文字颜色、添加下划线等 - 正则匹配逻辑支持任意数量的标记对,不会出现多匹配、漏匹配问题
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

