18

I have an UIWebView in one tab that loads in viewDidLoad, but if user taps other tab the loading will be disrupted and - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error will be called, but I want to know how can check if webView is loaded if user taps the previous tab again, and if it's not loaded it will reload it, something like this

  -(void)viewWillAppear:(BOOL)animated
{
    if (!webView)
        {
          NSURL *url = [NSURL URLWithString:@"url"];
          NSURLRequest *request = [NSURLRequest requestWithURL:url];
          [webView loadRequest:request];
        }

    }

But it's not working, help please?

vburojevic
  • 1,666
  • 5
  • 24
  • 34
  • The only solution (I found) which works ok: http://stackoverflow.com/questions/1662565/uiwebview-finished-loading-event/25620001#25620001 – sabiland Sep 02 '14 at 09:25

4 Answers4

28

UIWebview has a webViewDidFinishLoad delegate method. Set a bool to indicate this was done.

- (void)webViewDidStartLoad:(UIWebView *)webView {

 webViewDidFinishLoadBool = NO;
 loadFailedBool = NO;

}


- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

 loadFailedBool = YES;
}


- (void)webViewDidFinishLoad:(UIWebView *)webView {

   if (!loadFailedBool)
   webViewDidFinishLoadBool = YES;

}
Zigglzworth
  • 6,645
  • 9
  • 68
  • 107
8

If you haven't got it to work yet, here is a working example. It also shows an alert when failing to load, and the alert is only shown once.

Header:

@interface MyViewController : UIViewController <UIWebViewDelegate> {
    BOOL wasLoaded;
    BOOL alertWasShown;
}

@property (nonatomic, retain) IBOutlet UIWebView *myWebView;

@end

Implementation:

- (void)loadWebView:(NSString *)urlString {
    if (wasLoaded == NO) {
        NSURL *url = [NSURL URLWithString:urlString];
        NSURLRequest *requestObject = [NSURLRequest requestWithURL:url];
        [myWebView loadRequest:requestObject];
    }
}

- (void)viewWillAppear:(BOOL)animated {
    NSString *urlString = @"put your url here";
    [self loadWebView:urlString];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    wasLoaded = NO;
    alertWasShown = NO;
    myWebView.delegate = self;
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    // Not necessary to do anything here.
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    wasLoaded = YES; // Indicates that it finished loading.
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    if (alertWasShown == NO) {
        UIAlertView *alert = ... // Create an alert.
        [alert show];

        alertWasShown = YES;
    }
}

I hope that helps.

matsr
  • 4,302
  • 3
  • 21
  • 36
1

It is true that the original question was posted many years ago. Recently I had to find a reliable solution to this issue.

Here is the solution that worked for me:

  1. Replaced UIWebView with WKWebWiew.
  2. Added 'evaluateJavaScript' code while handling the 'didFinishNavigation' delegate method.

The complete code is:

   - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
    [webView evaluateJavaScript:@"document.body.innerHTML" completionHandler:^(id result, NSError *error) {
        if (result != nil) {
            // Call your method here
        }
        if(error) {
            NSLog(@"evaluateJavaScript error : %@", error.localizedDescription);
        }
    }];
}
Nish
  • 545
  • 5
  • 7
0

For pages with multiple frames, UIWebView.loading property should also be used.

Apple's doc: @property(nonatomic, readonly, getter=isLoading) BOOL loading A Boolean value indicating whether the receiver is done loading content.

If YES, the receiver is still loading content; otherwise, NO.

In iOS6 (beta 4) it looks like Apple has fixed some issues with this property as well. http://code-gotcha.blogspot.fi/2012/08/uiwebviewloading-in-ios-6-fixed.html

Mazed
  • 499
  • 4
  • 4