SwiftUI中如何为TextEditor内的单个单词修改背景颜色
SwiftUI 实现TextEditor单个单词自定义背景色

原生SwiftUI TextEditor 没有提供局部文本样式自定义的公开API,要实现单词级背景高亮,需要封装底层的UITextView(iOS)/NSTextView(macOS),通过TextKit的属性字符串能力给指定单词添加背景属性,以下是Swift 5下可直接运行的实现:
iOS端实现代码
import SwiftUI struct HighlightTextEditor: UIViewRepresentable { @Binding var text: String /// key: 需要高亮的单词,value: 对应背景色 let highlightRule: [String: UIColor] func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.font = .systemFont(ofSize: 16) textView.delegate = context.coordinator return textView } func updateUIView(_ textView: UITextView, context: Context) { // 记录光标位置,避免输入时光标跳转到末尾 let cursorPosition = textView.selectedRange let totalLength = text.utf16.count let attrStr = NSMutableAttributedString(string: text) // 设置全局默认文本样式 attrStr.addAttributes([ .font: UIFont.systemFont(ofSize: 16), .foregroundColor: UIColor.label ], range: NSRange(location: 0, length: totalLength)) // 遍历所有高亮规则,匹配单词位置 for (word, bgColor) in highlightRule { let escapedWord = NSRegularExpression.escapedPattern(for: word) guard let regex = try? NSRegularExpression(pattern: "\\b\(escapedWord)\\b", options: .caseInsensitive) else { continue } let matches = regex.matches(in: text, range: NSRange(location: 0, length: totalLength)) matches.forEach { match in attrStr.addAttribute(.backgroundColor, value: bgColor, range: match.range) } } textView.attributedText = attrStr // 恢复光标位置 textView.selectedRange = cursorPosition } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } class Coordinator: NSObject, UITextViewDelegate { let parent: HighlightTextEditor init(parent: HighlightTextEditor) { self.parent = parent } func textViewDidChange(_ textView: UITextView) { parent.text = textView.text } } } // 调用示例 struct DemoView: View { @State private var content = "This is a sample text, we will highlight sample and text words with different background colors." private let highlightConfig = [ "sample": UIColor.yellow.withAlphaComponent(0.4), "text": UIColor.systemBlue.withAlphaComponent(0.3) ] var body: some View { HighlightTextEditor(text: $content, highlightRule: highlightConfig) .padding() } }
适配说明
- macOS端适配:将
UIViewRepresentable替换为NSViewRepresentable,UITextView替换为NSTextView,对应代理方法切换为NSTextViewDelegate的实现,核心的属性字符串高亮逻辑无需修改。 - 匹配规则:代码中使用
\b单词边界做正则匹配,只会匹配完整独立单词,不会误匹配单词中包含的子串,如果需要模糊匹配可以自行修改正则规则。 - 如果需要实现圆角效果的背景高亮,无法直接通过属性字符串完成,需要自定义
NSLayoutManager重写背景绘制逻辑。
内容的提问来源于stack exchange,提问作者Thomas FONTAINE
相关产品推荐
相关产品推荐

