Reputation: 880
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 before 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!
Upvotes: 6
Views: 6195
Reputation: 12625
For me this was an improvement in terms of getting a larger more appropriate number, but I'm still not sure it's completely right.
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.webView.evaluateJavaScript("document.readyState") { [weak self] (complete, error) in
if complete != nil {
self?.webView.evaluateJavaScript("document.body.scrollHeight"){ [weak self] (result, error) in
if let height = result as? CGFloat {
self?.updateHeight(height + 80)
}
}
}
}
}
}
Upvotes: 0
Reputation: 899
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.
Upvotes: 12