SwiftUI中RichEditorView发送/编辑时内容无法更新的问题求助
解决方案:修复RichEditorView的内容同步问题
问题根源
你的RichTextEditor实现中,updateUIView方法是空的。SwiftUI在绑定的htmlText值发生变化时会调用这个方法,但你没有将新的内容同步到RichEditorView实例,导致编辑器显示的内容无法跟随绑定值更新(比如发送后清空、编辑回填场景)。同时,直接同步可能触发双向绑定的循环更新,需要添加内容一致性判断。
核心修复步骤
- 实现
updateUIView方法:同步绑定的htmlText到编辑器,同时避免循环更新 - 优化内容变化回调:确保编辑器内容变化时仅在必要时更新绑定值
修改后的完整代码
struct RichTextEditor: UIViewRepresentable { class Coordinator: RichEditorDelegate, RichEditorToolbarDelegate { var parent: RichTextEditor var isDefaultFocus: Bool @Binding var colorPickerType: ColorPickerType? init(_ parent: RichTextEditor, isDefaultFocus: Bool = false, colorPickerType: Binding<ColorPickerType?>) { self.parent = parent self.isDefaultFocus = isDefaultFocus self._colorPickerType = colorPickerType NotificationCenter.default.addObserver(self, selector: #selector(colorPicked(notification:)), name: AppNotifications.colorPicked, object: nil) } func richEditorTookFocus(_ editor: RichEditorView) { } func richEditorLostFocus(_ editor: RichEditorView) { } // 优化:仅当内容不同时更新绑定值,避免循环 func richEditor(_ editor: RichEditorView, contentDidChange content: String) { if content != parent.htmlText { parent.htmlText = content } } func richEditorToolbarChangeTextColor(_ toolbar: RichEditorToolbar) { colorPickerType = .text } func richEditorToolbarChangeBackgroundColor(_ toolbar: RichEditorToolbar) { colorPickerType = .background } func richEditorToolbarInsertLink(_ toolbar: RichEditorToolbar) { if let hasSelection = toolbar.editor?.hasRangeSelection, hasSelection, let href = toolbar.editor?.runJS("document.getSelection().getRangeAt(0).toString()"){ toolbar.editor?.insertLink(href, title: "Link") } } func richEditorDidLoad(_ editor: RichEditorView) { editor.setEditorBackgroundColor(UIColor(parent.editorBackgroundColor)) editor.setEditorFontColor(UIColor(Color.primary)) if isDefaultFocus { editor.focus() } } func richEditor(_ editor: RichEditorView, heightDidChange height: Int) { withAnimation { if CGFloat(height) > parent.maxHeight { parent.height = parent.maxHeight } else if CGFloat(height) < parent.minHeight { parent.height = parent.minHeight } else if CGFloat(height) != parent.height { parent.height = CGFloat(height) } } } @objc func colorPicked(notification: NSNotification) { if let colorPickerType = notification.userInfo?["colorPickerType"] as? ColorPickerType, let selectedColor = notification.userInfo?["color"] as? UIColor { switch colorPickerType { case .text : self.parent.toolbar.editor?.setTextColor(selectedColor) case .background : self.parent.toolbar.editor?.setTextBackgroundColor(selectedColor) } } } } func makeCoordinator() -> Coordinator { Coordinator(self, isDefaultFocus: isDefaultFocus, colorPickerType: $colorPickerType) } @Binding var htmlText: String @Binding var colorPickerType: ColorPickerType? var isDefaultFocus : Bool var minHeight: CGFloat @Binding var height: CGFloat var maxHeight: CGFloat let toolbar: RichEditorToolbar = RichEditorToolbar(frame: CGRect(x: 0, y: 0, width: 100, height: 44)) var editorBackgroundColor = Color.red func makeUIView(context: Context) -> RichEditorView { let editor = RichEditorView(frame: .zero) editor.delegate = context.coordinator editor.html = htmlText editor.isScrollEnabled = true editor.placeholder = "Write something..." toolbar.options = [ RichEditorDefaultOption.bold, RichEditorDefaultOption.italic, RichEditorDefaultOption.strike, RichEditorDefaultOption.underline, RichEditorDefaultOption.textColor, RichEditorDefaultOption.textBackgroundColor, RichEditorDefaultOption.link, RichEditorDefaultOption.orderedList, RichEditorDefaultOption.unorderedList, RichEditorDefaultOption.indent, RichEditorDefaultOption.outdent, RichEditorDefaultOption.alignLeft, RichEditorDefaultOption.alignCenter, RichEditorDefaultOption.alignRight, ] toolbar.editor = editor toolbar.delegate = context.coordinator editor.inputAccessoryView = toolbar return editor } // 新增:同步绑定值到编辑器,避免循环更新 func updateUIView(_ uiView: RichEditorView, context: Context) { if uiView.html != htmlText { uiView.html = htmlText } } }
额外优化建议
- 编辑消息时,如果需要自动聚焦编辑器,可以在
updateUIView中添加逻辑:当htmlText非空且是编辑场景时,调用uiView.focus() - 若编辑器初始化时内容未正确加载,可以在
richEditorDidLoad中再次设置editor.html = parent.htmlText
内容的提问来源于stack exchange,提问作者Vikash Kumar Chaubey
相关产品推荐
相关产品推荐

