SwiftUI中TextEditor值未更新求助:点击更新按钮文本颜色重置
问题原因
你的代码存在两个核心问题导致点击更新后文本重置:
- 单向绑定缺失:
HighlightedTextEditor只实现了从@Binding到UITextView的内容同步,但没有把用户在UITextView中编辑的内容同步回绑定的attributedText,所以点击更新时,你操作的还是初始的文本内容,而非用户编辑后的内容。 - 不必要的强制覆盖:
updateUIView方法每次都会强制设置uiView.attributedText = attributedText,这会导致用户编辑的内容被旧值覆盖,进一步加剧了重置问题。
修复后的完整代码
import SwiftUI class TextColorUpdater: ObservableObject { @Published var attributedText: NSAttributedString init(initialText: String) { self.attributedText = TextColorUpdater.highlightText(initialText) } func update() { self.attributedText = TextColorUpdater.highlightText(attributedText.string) } static func highlightText(_ text: String) -> NSAttributedString { let mutableAttributedString = NSMutableAttributedString(string: text) if let regex = try? NSRegularExpression(pattern: "\\bred\\b", options: .caseInsensitive) { let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count)) for match in matches { let nsRange = match.range mutableAttributedString.addAttribute(.foregroundColor, value: UIColor.red, range: nsRange) } } return mutableAttributedString } } struct HighlightedTextEditor: UIViewRepresentable { @Binding var attributedText: NSAttributedString func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.isEditable = true textView.isSelectable = true textView.delegate = context.coordinator textView.attributedText = attributedText return textView } func updateUIView(_ uiView: UITextView, context: Context) { // 仅当绑定的文本与当前文本不同时才更新,避免覆盖用户编辑内容 if uiView.attributedText.string != attributedText.string { uiView.attributedText = attributedText } } class Coordinator: NSObject, UITextViewDelegate { var parent: HighlightedTextEditor init(_ parent: HighlightedTextEditor) { self.parent = parent } func textViewDidChange(_ textView: UITextView) { // 将编辑后的内容同步回绑定的属性 parent.attributedText = textView.attributedText } } } struct ContentView: View { @StateObject var textColorUpdater = TextColorUpdater(initialText: "This is a redd red red red car. The sky is not red") var body: some View { VStack { HighlightedTextEditor(attributedText: $textColorUpdater.attributedText) .frame(height: 200) .border(Color.gray) Button("Update") { textColorUpdater.update() } .padding() } .padding() } }
关键修复点
- 添加协调器(Coordinator):实现
UITextViewDelegate,通过textViewDidChange方法将用户编辑的内容实时同步回@Binding的attributedText,确保点击更新时使用的是最新文本。 - 优化updateUIView逻辑:增加判断,只有当绑定文本的字符串内容与UITextView当前内容不同时才更新,避免用户编辑过程中被强制覆盖。
- 完善视图布局:给TextEditor添加高度和边框,提升交互体验(可选,但更直观)。
内容的提问来源于stack exchange,提问作者Karl Ehrlich
相关产品推荐
相关产品推荐

