The mclin answer is correct that the UIWebView is performing loads in the background. If everything you download is simple html and the tags have no content like src = "...", then you can be pretty sure that the webViewDidFinishLoad method (the UIWebViewDelegate protocol method) will be called only once and that you can execute your javascript in this deletet method.
However, UIWebView, after loading the HTML bootstrap, will load any images, javascript, audio, video, etc., and webViewDidFinishLoad will be called when each of these subsequent loads is completed. I think if you look at the Safari progress bar on your iPhone, you can see this behavior. The progress bar goes about halfway after loading the start page, and then moves a little bit as the images or what you have downloaded.
I tried several methods to run javascript after the page has finished loading. It will be easier to make webViewDidFinishLoad execute another selector after a short delay and check the load property of webView. You take a little risk here by taking “time” and “flows” together, but hey ... if you want it easily (that's what it is).
-(void) checkIfLoadDone:(UIWebView *) webView { if (webView.loading) { return; }
A more sophisticated method is to track loads individually and maintain a counter. When the counter returns to 0, you can run your javascript. In this case, you will need to implement the delegation method for
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (navigationType != UIWebViewNavigationTypeOther) { self.outStandingLoads = 0; } return YES; }
Now you can have webViewDidStartLoad: increment outStandingLoads and have webViewDidFinishLoad: and webView: didFailLoadWithError: decrement and checkStandingLoads. I would use the NSInteger atomic property for outStandingLoads in all code to eliminate the potential for loading more than one thread.
I think that any of the methods will work quite well. I chose the latter approach, but only because I needed to solve other problems in webViewDelegate calls. I decided to extend the UIWebView and make it my delegate, where my extension implemented the delegate methods. Then I use the NSNotification model to send notifications like "WebPageLoadBegan" and "WebPageLoadComplete" to communicate with my user interface code. It seemed to me a lighter model when working with two different sets of user interface code ... iPad and iPhone.
Hope this helps.
Drew gonczi
source share