How Do I show HTML in SwiftUI with WKWebView?

Viewed 108

I've got html data out of json, and want to let it show it in swiftUI. But it only takes a few days without progress.

Below is my HTML View

import UIKit
import SwiftUI
import WebKit


struct HTMLView: UIViewRepresentable {
    

    let htmlString: String
    
    @Binding var dynamicHeight: CGFloat
    
    var webView: WKWebView = WKWebView()

    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: HTMLView

        init(_ parent: HTMLView) {
            self.parent = parent
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
                DispatchQueue.main.async {
                    self.parent.dynamicHeight = height as! CGFloat
                }
            })
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    

    
    func makeUIView(context: Context) -> WKWebView {
        
        webView.loadHTMLString(htmlString, baseURL: nil)

        
        return webView
    }
    


    
    func updateUIView(_ uiView: WKWebView, context: Context)  {
        
        
            print("Height of \(htmlString) is \(self.dynamicHeight)")


    }
    
 
    
    
}

Every time I try the simulator with my I phone, "Height of (some html....) is 0.0" is printed. And this is my view

struct DetailedDrugInfo : View {

var xmlString: String
var infoTitle: String
var spacing: CGFloat
@State private var htmlViewHeight: CGFloat = .zero

var body: some View {
    
    VStack(alignment: .leading, spacing: spacing){


           .
           .
           .
           .
            
            ForEach($0.paragraph, id: \.self){i in
                
                let headerString = "<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'></header>"
                let stringHTML = headerString + i
                
                HTMLView(htmlString: stringHTML, dynamicHeight: $htmlViewHeight)
                    .frame(height : htmlViewHeight)
                    //.frame(height: 100) <-if I put CGFloat rather than dynamicHeight, HTMLView shows. 
                

                
                
            }
        }
        
    }
    .padding(.bottom)
    
}

}

If I put CGFloat below HTMLView rather than dynamicHeight, HTMLView shows but with all the same heights no matter there are a hundred lines in that document or just one line in it.

I desperately want to adopt dynamic height to the HTML View.

0 Answers
Related