0

I am working on a SwiftUI project, the functionalities it required is to make a Rich Text Editor on IOS.

The approach I am following is fairly simple, I used cbess/RichTextEditor link originally written in UIKit and import it into SwiftUI. To run the imported UIView, I wrap the view inside one UIViewRpresentable and add it into the ContentView struct of SwiftUI.

Now, I want to publish the data inside UIView and assign it to one of @state ContentView owns.

The code structure look similar to this:

For the ContentView (SwiftUI)

struct ContentView: View { 
    @State var textHtml: String = "" //I want all changes come from UIView be stored inside this
    var body: some View {
        VStack {
            Cbess(
                frameEditor: CGRect(x: 0, y: 40, width: 360, height: 400)
            )
        }
    }
}

For the UiViewRepresentable

struct Cbess : UIViewRepresentable{

    let frameEditor : CGRect

    func makeUIView(context: Context) -> UIView {
        
        let frameEditor = RichEditorView(frame: frameEditor)
        
        let uiView : UIView = UIView()
        uiView.addSubview(editorView)
        return uiView
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
    }
}

For the UiView(Simplified)

@objcMembers open class RichEditorView: UIView,  {
    var contentHTML : String // This variable get updated regularly

}

One additional question is that I want to make a Rich Text Editor by solely SwiftUI. How can I achieve it? Can you give me some keywords? Some Repo?

Any help is very appreciated! Thanks for read this whole question.

1 Answers1

0

Use @Binding and delegate.

UIViewRepresentable view

struct Cbess : UIViewRepresentable {
    
    @Binding var textHtml: String
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    func makeUIView(context: Context) -> RichEditorView {
        
        let editorView = RichEditorView()
        editorView.delegate = context.coordinator
        return editorView
    }
    
    func updateUIView(_ uiView: RichEditorView, context: Context) {
    }
    
    class Coordinator: NSObject, RichEditorDelegate {
        
        var parent: Cbess
        
        init(_ parent: Cbess) {
            self.parent = parent
        }
        
        // Use delegate here
        func richEditor(_ editor: RichEditorView, contentDidChange content: String) {
            self.parent.textHtml = content
            print(content)
        }
    }
}

Your content view:

struct ContentView: View {
    @State var textHtml: String = ""
    var body: some View {
        VStack {
            Cbess(textHtml: $textHtml)
                .frame(width: 360, height: 400)
            
            Text("Print----\n\(textHtml)")
        }
    }
}

Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • Thank you so much! I wish I got enough reputation to upvote yours answer :'( – Hoàng Sơn Jan 16 '21 at 06:45
  • However, can you elaborate a little bit on the purpose of Coordinate inside UIViewRepresentable? Or at least give me some more keywords on the Coordinate class and NsObject? :v – Hoàng Sơn Jan 16 '21 at 06:47