How to calculate the height of WKWebView content?

For UIWebView, we can get the height of the content as follows:

[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] 

But WKWebView does not have this method, and webView.scrollView.contentSize.height is not right.

 (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { } 

Thank you for your help!

+8
wkwebview
source share
4 answers

I solved this problem with KVO.

First, addObserver for WKWebView scrollView contentSize like this:

 addObserver(self, forKeyPath: "webView.scrollView.contentSize", options: .New, context: nil) 

And then, get the change as follows:

 override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { if keyPath == "webView.scrollView.contentSize" { if let nsSize = change[NSKeyValueChangeNewKey] as? NSValue { let height = nsSize.CGSizeValue().height // Do something here using content height. } } } 

Easy to get height for web browsing content.

Remember to remove the observer:

 removeObserver(self, forKeyPath: "webView.scrollView.contentSize", context: nil) 

I am scrolling this line in deinit .

+8
source share

You can do it as follows:

 self.webview.navigationDelegate = self; - (void)webView:(WKWebView *)webview didFinishNavigation:(WKNavigation *)navigation{ // webview.scrollView.contentSize will equal {0,0} at this point so wait [self checkIfWKWebViewReallyDidFinishLoading]; } - (void)checkIfWKWebViewReallyDidFinishLoading{ _contentSize = _webview.scrollView.contentSize; if (_contentSize.height == 0){ [self performSelector:@selector(WKWebViewDidFinishLoading) withObject:nil afterDelay:0.01]; } } 
+2
source share

EDIT:

To get the best possible height calculation, in the end I did a few things to get the maximum height:

  • I set the size of the web view to be really large and then loaded the content.
  • After loading the content (KVO notification) I resize the view using the method below.
  • Then I ran the size function again and I got a new size and resized my view again.

The above results got the most accurate results for me.

ORIGINAL:

I tried looking at the KVO scroll and I tried to evaluate javascript in the document using clientHeight , offsetHeight etc.

What ultimately happened to me: document.body.scrollHeight . Or use scrollHeight your top element, for example. container div .

I am listening to changes to the loading properties of WKWebview using KVO:

 [webview addObserver: self forKeyPath: NSStringFromSelector(@selector(loading)) options: NSKeyValueObservingOptionNew context: nil]; 

And then:

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { if(object == self.webview && [keyPath isEqualToString: NSStringFromSelector(@selector(loading))]) { NSNumber *newValue = change[NSKeyValueChangeNewKey]; if(![newValue boolValue]) { [self updateWebviewFrame]; } } } 

Implementation of updateWebviewFrame :

 [self.webview evaluateJavaScript: @"document.body.scrollHeight" completionHandler: ^(id response, NSError *error) { CGRect frame = self.webview.frame; frame.size.height = [response floatValue]; self.webview.frame = frame; }]; 
+2
source share

WKWebView did not finish loading when FinishNavigation is called - is there an error in WKWebView? WKWebView does not use delegation, so you know when the content download is complete. You can create a new stream to check the status of WKWebView.

 override func viewDidLoad() { super.viewDidLoad() dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { while(self.webView?.loading == true){ sleep(1) } dispatch_async(dispatch_get_main_queue(), { print(self.webView!.scrollView.contentSize.height) }) }) } 
0
source share

All Articles