I am taking a screenshot of a WKVebView in the completion handler of a javascript evaluation:
func loadPage(){
let fileURL = URL(fileURLWithPath: "...")
let baseUrl = URL(fileURLWithPath: "...")
webView?.navigationDelegate = self
webView.loadFileURL(fileURL, allowingReadAccessTo: baseUrl)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("....") { (result, error) in
let configuration = WKSnapshotConfiguration()
configuration.rect = CGRect(origin: .zero, size: (self.webView?.frame.size)!)
self.webView!.takeSnapshot(with: configuration, completionHandler: { (image, error) in
// do something with the image
})
}
Even if it is in the completion handler of the webView.evaluateJavaScript
function, the content if often not finished to render and I am getting either blank screenshot or partial ones (only some elements are present).
How can I ensure that rendering is completed before taking screenshot (I do not want to introduce fixed delay)
As content of WebView is bigger than the screen size so first we will get height and width of the content after that we will take a screenshot
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Will get Height and Width of the Content
self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
guard let contentHeight = height as? CGFloat else { print("Content height could not be obtained"); return }
self.webView.evaluateJavaScript("document.body.scrollWidth", completionHandler: { [weak self](width, error) in
let contentWidth = width as! CGFloat
let rect = CGRect(x: 0, y: 0, width: contentWidth, height: contentHeight)
self?.takeScreenshot(rect)
})
})
}
})
}
Once we will get the Height and Width, we will call below method to capture Screenshot
func takeScreenshot(_ rect: CGRect) {
webView.evaluateJavaScript(".....") { (result, error) in
let configuration = WKSnapshotConfiguration()
configuration.rect = rect//CGRect(origin: .zero, size: (self.webView?.frame.size)!)
self.webView!.takeSnapshot(with: configuration, completionHandler: { (image, error) in
// do something with the image
print("image:\(image!)")
})
}
}
Hope it will help you.