1

I'm trying to show some HTML text in an app I'm making, but I can't get it to work properly. The problem is that the view that contains the text is always shown with the height of only one line, even tho it is wrapped in a ScrollView. In the screenshot, you guys can see that the ScrollView works, but the original size is very small.

enter image description here

The code is:

ScrollView {
                GeometryReader { proxy in
                    AttributedText(htmlContent: job.description)
                        .frame(height: proxy.size.height, alignment: .center)
                }
            }

struct AttributedText: UIViewRepresentable {
    let htmlContent: String
    
    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.loadHTMLString(htmlContent, baseURL: nil)
    }
}

struct AttributedText_Previews: PreviewProvider {
    static var previews: some View {
        AttributedText(htmlContent: "<h1>This is HTML String</h1>")
    }
}

I have also tried to use the GeometryReader to establish the size of the ScrollView, but no luck either.

Is there any way to make this look normal and nice, scrollable, and with a proper text size?

Thanks a lot in advance!

Edit: After @RajaKishan's answer, this is how it looks like (where you can see that the content is cut-off):

enter image description here

noloman
  • 11,411
  • 20
  • 82
  • 129

1 Answers1

3

As WKWebView has already scroll and you are also wrapped inside the scroll view, so parent scroll view not get the proper size. You have to disable WKWebView scrolling. Also, bind the size with webview and update the frame of webview.

Here is the possible demo.

struct AttributedText: UIViewRepresentable {
    let htmlContent: String
    @Binding var size: CGSize
    
    private let webView = WKWebView()
    var sizeObserver: NSKeyValueObservation?
    
    func makeUIView(context: Context) -> WKWebView {
        webView.scrollView.isScrollEnabled = false //<-- Here
        webView.navigationDelegate = context.coordinator
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.loadHTMLString(htmlContent, baseURL: nil)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: AttributedText
        var sizeObserver: NSKeyValueObservation?
        
        init(parent: AttributedText) {
            self.parent = parent
            sizeObserver = parent.webView.scrollView.observe(\.contentSize, options: [.new], changeHandler: { (object, change) in
                parent.size = change.newValue ?? .zero
            })
        }
    }
}

For view

@State private var size: CGSize = .zero

var body: some View{
    ScrollView {
        AttributedText(htmlContent: "<h1>This is HTML String</h1>", size: $size)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, idealHeight: size.height, maxHeight: .infinity)
    }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • Unfortunately, it doesn't work because now it doesn't scroll at all. So now I only see one line without any chance to scroll the content – noloman May 16 '21 at 10:28
  • thanks! Indeed it looks so much better! but I still can't scroll if the content occupies more than the height of the screen. @RajaKishan I'm adding a small video of how it is now in the original post – noloman May 16 '21 at 11:19
  • I check this it scrolls the whole conten. – Raja Kishan May 16 '21 at 11:30
  • 1
    it worked now like a charm! thanks a lot! you're the best! – noloman May 16 '21 at 11:46