Home > OS >  Delegate for external link clicked in SwiftUI HtmlView
Delegate for external link clicked in SwiftUI HtmlView

Time:10-06

I'm using a HTMLView from this answer

But sometimes I have a link, if I click that opens Safari

Does exist in SwiftUI some delegate to catch the link with this HTMLView?

CodePudding user response:

You can set the UITextDelegate of the UITextView to the Coordinator of the UIViewRepresentable. Then, you can decide how to process URLs in shouldInteractWith. If you return false, the system will not use Safari to navigate to the URL.

struct HTMLFormattedText: UIViewRepresentable {
    
    let text: String
    
    init(_ content: String) {
        self.text = content
    }
    
    class Coordinator : NSObject, UITextViewDelegate {
        func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
            print(URL)
            return false
        }
    }
    
    func makeUIView(context: UIViewRepresentableContext<Self>) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<Self>) {
        DispatchQueue.main.async {
            if let attributeText = self.converHTML(text: text) {
                uiView.attributedText = attributeText
            } else {
                uiView.text = ""
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
    
    private func converHTML(text: String) -> NSAttributedString?{
        guard let data = text.data(using: .utf8) else {
            return nil
        }
        
        if let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
            return attributedString
        } else{
            return nil
        }
    }
}

struct ContentView: View {
    var body: some View {
        HTMLFormattedText("Test<br/><a href=\"https://google.com\">Google</a>")
    }
}
  • Related