WKWebView didn't finish loading, when didFinishNavigation is called - Bug in WKWebView?
ios, objective-c, swift, webview
Solution
WKWebView doesn't use delegation to let you know when content loading is complete (that's why you can't find any delegate method that suits your purpose). The way to know whether a WKWebView is still loading is to use KVO (key-value observing) to watch its `loading` property. In this way, you receive a notification when `loading` changes from `true` to `false`.
Here's a looping animated gif showing what happens when I test this. I load a web view and respond to its `loading` property through KVO to take a snapshot. The upper view is the web view; the lower (squashed) view is the snapshot. As you can see, the snapshot does capture the loaded content:
[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
if (self->_webKitView.isLoading == true) {
NSLog(@"Still loading...");
}else {
NSLog(@"Finished loading...");
[timer invalidate];
dispatch_async(dispatch_get_main_queue(), ^{
[self->_activityIndicator stopAnimating];
});
}
}];
Problem
Goal: To take a screenshot of WKWebView after the website finished loading Method employed: - Defined a WKWebView var in UIViewController Created an extension method called screen capture() that takes image of WKWebView Made my UIViewController to implement WKNavigationDelegate Set the wkwebview.navigationDelegate = self ( in the UIViewController init) Implemented the didFinishNavigation delegation func in UIViewcontroller to call screen capture extension method for WKWebView ``` func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) { let img = webView.screenCapture() } ``` Questions: - When I debug i simulator, I notice that the control reaches the didFinishNavigation() func even though the website has not yet rendered in the WKWebView - Correspondingly the image screenshot taken is a white blob. What am I missing here? I looked at all possible delegate functions for WKWebView and nothing else seem to represent the completion of content loading in WKWebView. Would appreciate help on if there is a work around Update: Adding screenshot code that I am using to take a screenshot for web view ``` class func captureEntireUIWebViewImage(webView: WKWebView) -> UIImage? { var webViewFrame = webView.scrollView.frame if (webView.scrollView.contentSize != CGSize(width: 0,height: 0)){ webView.scrollView.frame = CGRectMake(webViewFrame.origin.x, webViewFrame.origin.y, webView.scrollView.contentSize.width, webView.scrollView.contentSize.height) UIGraphicsBeginImageContextWithOptions(webView.scrollView.contentSize, webView.scrollView.opaque, 0) webView.scrollView.layer.renderInContext(UIGraphicsGetCurrentContext()) var image:UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() webView.scrollView.frame = webViewFrame return image } return nil } ```