0

I have a Coordinator running evaluateJavascript on WkWebView didFinish.

The evaluate is getting the document.body.scrollHeight of the webView:

extension WebView {
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView

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

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

It's working fine for small web views, but for very large web views (HTML passed directly into WKWebView to render), the initial scrollHeight value returned from evaluateJavascript is incorrect.

For instance, with the above self.parent.dynamicHeight is returning 204187 when it should be 21675.

If I wait 1 second after didFinish to evaluate, it's returning the correct value of 21675, using a temp async/await task:

extension WebView {
    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView

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

        public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            
            if webView.isLoading == false {
                Task.init {
                    do {
                        try await Task.sleep(nanoseconds: 1_500_000_000)
                        let result = try await webView.evaluateJavaScript("document.documentElement.scrollHeight")
                        self.parent.dynamicHeight = result as! CGFloat
                    } catch {
                        print(error)
                    }
                }
            }
        }
    }
}

While the above async task works, it's causing 1 second delays in rendering the Webview, and XCode is warning about WKWebView.evaluateJavaScript(_:completionHandler:) must be used from main thread only.

Regardless, I don't understand how it's returning the incorrect scrollHeight initially if didFinish should execute after the webview is finished loading.

Safari inspection of the Webview shows the HTML and BODY both have the correct height size.

Is there something I'm missing?

alyx
  • 2,593
  • 6
  • 39
  • 64
  • Does this answer your question https://stackoverflow.com/a/59790493/12299030? – Asperi Jun 16 '22 at 13:30
  • The Coordinator above, and the rest of the relevant code in my project is a modified version of the code snippet from the accepted answer in that SO question, so this is an issue which includes that accepted answer – alyx Jun 16 '22 at 14:09
  • If you'd gave a reference of used code in question I would not comment. Btw, that code still works for me. – Asperi Jun 16 '22 at 14:20
  • It's a library which uses the SO answer: https://github.com/NuPlay/RichText . As I mentioned, for very large HTML files being loaded in WKWebView, it's giving incorrect initial scrollHeight values. For smaller files it works fine as mentioned – alyx Jun 16 '22 at 14:21
  • 1
    Note that in the linked question, the accepted answer recommends checking `document.readyState` in addition, and also recommends setting constraints correctly. I think those 2 issues might be the reason for your problems. – timbre timbre Jun 16 '22 at 15:44
  • That worked thanks, I'll make a PR to the RichText git repo as well – alyx Jun 16 '22 at 16:32

0 Answers0