web-dev-qa-db-fra.com

UIWebView didFinishLoading se déclenche plusieurs fois

J'ai du code qui doit s'exécuter après que a UIWebView a fini de charger un document. Pour cela, j'ai défini le délégué de UIWebView sur mon contrôleur et implémenté la méthode webViewDidFinishLoading.

Cela est appelé plusieurs fois, selon le type de page à charger. Je ne sais pas si c'est à cause des demandes ajax, des demandes d'images ou peut-être même des iframes.

Existe-t-il un moyen de dire que la requête principale est terminée, ce qui signifie que le code HTML est complètement chargé?

Ou peut-être retarder le déclenchement de mon code jusqu'à ce que tous ces événements soient déclenchés?

52
Ben Scheirman

Il pourrait être instructif (si vous n'êtes pas allé aussi loin) de NSLog une trace de chargement commence et se termine.

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
       NSLog(@"Loading: %@", [request URL]);
       return YES;
    }


    - (void)webViewDidFinishLoad:(UIWebView *)webView {
       NSLog(@"didFinish: %@; stillLoading: %@", [[webView request]URL],
            (webView.loading?@"YES":@"NO"));
    }


    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
       NSLog(@"didFail: %@; stillLoading: %@", [[webView request]URL],
            (webView.loading?@"YES":@"NO"));
    }

Je viens de regarder les appels aux trois dans l'un de mes projets qui charge une page d'aide de mon bundle et contient des ressources intégrées (css externe, YUI !, images). La seule requête qui arrive est le chargement de page initial, shouldStartLoadWithRequest n'est appelé pour aucune des dépendances. Il est donc curieux de savoir pourquoi votre didFinishLoad est appelé plusieurs fois.

Peut-être que ce que vous voyez est dû à des redirections ou, comme mentionné, à des appels ajax dans une page chargée. Mais vous devriez au moins pouvoir équilibrer les appels à shouldStartLoad et à l'une des deux autres fonctions déléguées et être en mesure de déterminer quand le chargement est terminé.

48
wkw

Vous pouvez faire quelque chose comme ceci pour vérifier lorsque le chargement est terminé. Parce que vous pouvez avoir beaucoup de contenu sur la même page, vous en avez besoin.

- (void)webViewDidFinishLoad:(UIWebView *)webview  {
    if (webview.isLoading)
        return;
    // do some work
}
50
Scott Densmore

Vérifiez celui-ci de manière si simple et facile à réaliser, sans avoir besoin d'écrire trop de code:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
        if ([[webView stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) {
            // UIWebView object has fully loaded.
        }
    }
12
Vinod Singh

Cette question est déjà résolue, mais je vois qu'il manque une réponse qui explique en fait pourquoi plusieurs appels à webViewDidFinishLoad sont en fait un comportement attendu

La méthode susmentionnée est appelée à chaque fois que la vue Web termine le chargement d'un cadre. De la documentation du protocole UIWebViewDelegate :

webViewDidFinishLoad:
Envoyé après qu'une vue Web a fini de charger un cadre.

En fait, cela est également vrai pour toutes les autres méthodes qui composent le protocole UIWebViewDelegate.

8
Cezar

Essayez cela fonctionnera bien

 -(void)webViewDidFinishLoad:(UIWebView *)webview  
    {
       if (webview.isLoading)
           return;
       else
       {
           // Use the code here which ever you need to run after webview loaded 
       }
    }
7
Yogeesh H T

Cela se produit car la méthode de rappel est appelée à chaque fois qu'une trame est terminée de chargement. Afin d'éviter cela, définissez la propriété "suppressesIncrementalRendering" de la vue Web sur true. cela empêchera le rendu Web jusqu'à ce que toutes les données soient chargées dans la mémoire. Cela a fait l'affaire pour moi

3

J'ai remarqué quelque chose de similaire et c'était une confusion: j'ai un UITabBarController, il semble précharger tous les ViewControllers liés à ses onglets lors du lancement de l'application (bien qu'il ne montre que first_Tab_ViewController), donc lorsque plusieurs onglets ont ViewController avec WebView, leurs webViewDidFinishLoad respectifs sont appelés et si j'ai copié collé:

NSLog(@"size width %0.0f height %0.0f", fitingSize.width, fittingSize.height); 

dans plusieurs, j'obtiens plusieurs sorties dans la console qui semblent être un double appel alors qu'il s'agit vraiment d'un appel unique dans deux UIWebViews différents.

2
Luis

Vous pouvez vérifier les propriétés de chargement et de demande dans la méthode webViewDidFinishLoad

1
nico