29390

Getting the final rendered height of a static page in a WKWebView

Question:

In my app I’m using a WKWebView which loads webpages with static content.

I want to know the height of the contentSize as soon as the webpage is fully rendered in the WKWebView.

So I thought I could use the webView:didFinishNavigation: delegate for that:

import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { @IBOutlet weak var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() webView.navigationDelegate = self webView.uiDelegate = self webView.load(URLRequest(url: URL(string: "https://www.rockade.nl/testpage/testpage.php")!)) } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print("finished loading: height=\(webView.scrollView.contentSize.height)") } }

My problem with this code is that this delegate is called <i>before</i> the page is fully rendered, so I’m getting different results for the height, even values of 0.

When I add a small delay I’m getting the correct results, but that feels like a hack.

Using a observer like this

var myContext = 0 webView.scrollView.addObserver(self, forKeyPath: "contentSize", options: .new, context: &myContext) override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if context == &myContext { print(webView.scrollView.contentSize.height) } else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } }

doesn’t help me too, because I really need to be sure that a received value is the final height.

Good to know: I don’t have control over the webpages, so using javascript is not an option.

I hope someone can point me into the right direction!

Answer1:

So you don't have control over webpages but html dom is not changes on page to page. So you can use script to get the height of your page.

Maybe this helps to you:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in if complete != nil { webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in // Here is your height }) } }) }

PS: You can try 'document.body.offsetHeight' instead of scroll height also.

Recommend

  • Loading swf and using it through interface
  • Sending post data nsurlsession
  • Passing values between SWFs
  • Error getting audio input device sample rate: '!obj'
  • UIBarButtonItem - Argument of '#selector' cannot refer to local function - Swift 3
  • updatesearchresultsforsearchcontroller not called
  • windowScriptObject method not found on Objective-C code
  • Printing input from TextField to a Label in Xcode with Swift
  • Convert Func to Func
  • Custom Nav Title offset ios 11
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • Creating Java object from class name with constructor, which contains parameters [duplicate]
  • Loading .coffee files via a view in Rails
  • how to avoid repetitive constructor in children
  • Create DicomImage from scratch using Dcmtk
  • Functions in global context
  • Seeking advice on Jetty HttpClient Hang
  • Installing Hadoop, Java Exception about illegal characters at index 7?
  • Why is an OPTIONS request sent to the server?
  • Update CALayer sublayers immediately
  • Spring security and special characters
  • Deleting and Updating values from a cusrsor adapter
  • Optimizing database types to compact database (SQLite)
  • RectangularRangeIndicator format like triangular using dojo
  • Possible to stop flickering java tooltip in heavyweight mode?
  • Cross-Platform Protobuf Serialization
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • Do I've to free mysql result after storing it?
  • AT Commands to Send SMS not working in Windows 8.1
  • Circular dependency while pushing http interceptor
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Revoking OAuth Access Token Results in 404 Not Found
  • AngularJs get employee from factory
  • How to set the response of a form post action to a iframe source?
  • Change div Background jquery
  • Turn off referential integrity in Derby? is it possible?
  • apache spark aggregate function using min value
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • Sorting a 2D array using the second column C++
  • How to load view controller without button in storyboard?