UIWebView - How to determine the last webViewDidFinishLoad message?

The webViewDidFinishLoad message seems to be sent every time an any object is loaded on the page. Is there a way to determine that all content is loading?

+21
objective-c iphone uiwebview
May 25 '09 at 23:27
source share
10 answers

Interestingly, I would not have thought it would work. Although I'm sure there are other ways to do this (is there a way to extract the URL from the webViewDidFinishLoad message so that you can see which one is the main page that finishes loading?), The main thing I can think of is to use a evaluatedProgress to check move the page and release everything you want to do when it finishes loading 100%, which I do in my application. Google "iphone webview score progress" and click on the first link for a guide that I wrote about how to do this.

Update:

Please use my answer to phopkins instead of me! Using private APIs in your applications is a bad idea and you are likely to get a failure and its solution will be correct.

+9
May 26 '09 at 1:32
source share

I assume the iframe calls a pair of webViewDidStartLoad / webViewDidFinishLoad .

The [webView isLoading] check mentioned as an answer did not work for me; it returned false even after the first of two calls to webViewDidFinishLoad . Instead, I track the download as follows:

 - (void)webViewDidStartLoad:(UIWebView *)webView { webViewLoads_++; } - (void)webViewDidFinishLoad:(UIWebView *)webView { webViewLoads_--; if (webViewLoads_ > 0) { return; } … } - (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error { webViewLoads_--; } 

(Please note that this will only work if the starting / finished pairs do not appear in series, but in my experience this has not happened so far.)

+60
May 09 '10 at 3:54 a.m.
source share

Check this out, this will definitely work for you:

 - (void)webViewDidFinishLoad:(UIWebView *)webView { if ([[webView stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) { // UIWebView object has fully loaded. } } 
+18
Apr 23 '14 at 9:50
source share

Another way to track download progress with less control is to monitor WebViewProgressEstimateChangedNotification, WebViewProgressFinishedNotification, and WebViewProgressStartedNotification notifications. For example, you can watch these notifications to implement a simple progress indicator in your application. You update the progress indicator by calling the estimatedProgress method to get an estimate of the amount of downloaded content.

from http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html

+1
Aug 30 '12 at 8:22
source share

You can also use this short category I, which adds blocks to the UIWebView, and also allows you to choose between the default behavior of the UIWebView (receiving notification after each loading of the object) or the "expected" behavior (receiving notification only when the page is fully loaded) loaded).

https://github.com/freak4pc/UIWebView-Blocks

+1
Jan 02 '13 at 10:23
source share

I needed to grab a variable from a page that had not yet been fully loaded.

This worked for me:

 - (void) webViewDidFinishLoad:(UIWebView *)webView { NSString *valueID = [webView stringByEvaluatingJavaScriptFromString:@"document.valueID;"]; if([valueID isEqualToString:@""]){ [webView reload]; return; } //page loaded } 
+1
Jan 30 '14 at 13:14
source share

All options really didn't work for my use case. I used the phopkins example, slightly modified. I found that if the HTML uploaded to the webview contained an image that would be a separate request that occurred sequentially, so we should take this into account, and I did this with a timer. Not the best solution, but it seems to work:

 - (void)webViewActuallyFinished { _webViewLoads--; if (_webViewLoads > 0) { return; } //Actually done loading } - (void)webViewDidStartLoad:(UIWebView *)webView { _webViewLoads++; } - (void)webViewDidFinishLoad:(UIWebView *)webView { [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(webViewActuallyFinished) userInfo:nil repeats:NO]; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { _webViewLoads--; } 
+1
Feb 13 '14 at 22:20
source share

Hi, maybe a little back, but I hope this helps.

I just used the notification when it introduces the webViewDidFinishLoad method so that I can capture one instance of the method and then I will detect the notification and do my logic from there.

hope this helps. it does not capture the last invoked instance of the webViewDidFinishLoad method, but allows you to do something when it was called, rather than repeating calls to that particular method (for example, showing a button) too.

********* EDIT *********

I did a test and was able to test it. it really works, and the method called from the notification will be called after loading the full page.

Alternatively, I think you can do the counter using the delegation method webViewDidStartLoad, as well as the webViewDidFinishLoad, to make sure they are the same before you run your codes. this, however, is an ugly hack since we will never know how many times it will be called unless I load the html feed and you can add JavaScript to check how many elements there are on the page you are loading. I just use some of the methods that I was trying to solve. hope this helps.

Feedback is welcome. thank!

0
May 09 '12 at 4:05
source share

Here I use to show the spinner when the DOM boots, built on top of @ Vinod's answer.

Please note that between webViewDidStartLoad and webViewDidFinishLoad finished state is completed from the previous request (if any), then why the poll should start after webViewDidFinishLoad .

Possible values ​​for readyState: load, interactivity, or terminate (and possibly nil?)

 - (void)webViewDidStartLoad:(UIWebView *)webView { [self spinnerOn]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { [self startDOMCompletionPolling]; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { [self startDOMCompletionPolling]; } - (void)startDOMCompletionPolling { if (self.domCompletionListener) { [self.domCompletionListener invalidate]; } self.domCompletionListener = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(checkDOMCompletion) userInfo:nil repeats:YES]; } - (void)checkDOMCompletion { NSString *readyState = [self.webView stringByEvaluatingJavaScriptFromString:@"document.readyState"]; if (readyState != nil) { if (readyState.length > 0) { if ([readyState isEqualToString:@"loading"]) { //keep polling return; } } } //'completed', 'interactive', nil, others -> hide spinner [self.domCompletionListener invalidate]; [self spinnerOff]; } 
0
Mar 15 '16 at 13:47
source share

How do i do this:

 - (void)webViewDidFinishLoad:(UIWebView *)webview { if (webview.loading) return; // now really done loading code goes next [logic] } 
-5
Jun 21 '09 at 17:22
source share



All Articles