简体   繁体   中英

Can't get WKWebView content height correctly

I am trying to get the height of text rendered within a WKWebView so that I can later resize the view to fit it. I am using the code below, which does return a value via result . However if I shorten (or lengthen) htmlString , this value doesn't change. Any suggestions?

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

var webView: WKWebView!

var htmlString: String = "<!DOCTYPE html><html><body><p>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.</p></body></html>"

override func viewDidLoad() {
    super.viewDidLoad()

    //Instantiate with initial frame
    webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100), configuration: WKWebViewConfiguration())
    self.view.addSubview(webView)

    webView.loadHTMLString(htmlString, baseURL: nil)

    webView.evaluateJavaScript(("document.body.scrollHeight"), completionHandler: { result, error in
        print(result)
    })
}

}

The problem with your code is that you evaluate document.body.scrollHeight immediately after loading the HTML string. To get the correct height you have to wait until the HTML loads which takes some time, especially if it's the first time you are loading the HTML string.
That is why you have to evaluate document.body.scrollHeight in this delegate method:

 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
      webView.evaluateJavaScript("document.documentElement.scrollHeight") { (height, error) in
        print(height as! CGFloat)
      }
  }

I've written about this issue and how to find the correct height in situations where you use a custom font in CSS in this blog post .

following method should do a trick

      //to get height

          webView.evaluateJavaScript("document.height") { (result, error) in
            if error == nil {
                print(result)
            }
        }

        //to get width
        webView.evaluateJavaScript("document.width") { (result, error) in
            if error == nil {
                print(result)
            }
        }
  // to get contentheight of wkwebview
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {

   println(webView.scrollView.contentSize.height)

}

In order to get the exact height of the webView you should be sure that the webView is not on loading state. Here is the code that I used it.

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if webView.isLoading == false {
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
      if complete != nil {
        webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
          if error == nil {
            guard let height = height as? CGFloat else { return }
            webView.frame.size.height = height
            self.webViewContainerHeightConstraint.constant = height
            webView.sizeToFit()
            self.view.updateConstraints()
            self.view.updateConstraintsIfNeeded()
          }
        })
      }
    })
  }
}}

I had also a problem on iPhone 5s, the width was not correct. So I added this code, to ensure the correct frame.

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myWebView.frame = webViewContainer.bounds }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM