ios UIWebView didFinishLoading 多次触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1842370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:40:51  来源:igfitidea点击:

UIWebView didFinishLoading fires multiple times

iphoneiosobjective-cxcodeuiwebview

提问by Ben Scheirman

I have some code that needs to run after the a UIWebViewfinishes loading a document. For that I've set the UIWebView's delegate to my controller, and implemented the webViewDidFinishLoadingmethod.

我有一些代码需要在 aUIWebView完成加载文档后运行。为此,我已将UIWebView的委托设置为我的控制器,并实现了该webViewDidFinishLoading方法。

This gets called multiple times, depending on the type of page to load. I'm not sure if it's because of ajax requests, requests for images, or maybe even iframes.

这会被多次调用,具体取决于要加载的页面类型。我不确定是因为 ajax 请求、图像请求还是 iframe。

Is there a way to tell that the main request has finished, meaning the HTML is completely loaded?

有没有办法告诉主请求已经完成,这意味着 HTML 已完全加载?

Or perhaps delay my code from firing until all of those events are done firing?

或者可能延迟我的代码触发直到所有这些事件都触发?

采纳答案by wkw

It could be enlightening (if you haven't gone this far yet) to NSLog a trace of load starts and finishes.

它可能对 NSLog 有启发性(如果你还没有走这么远)加载开始和完成的痕迹。

    - (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"));
    }

I just watched the calls to all three in one of my projects which loads a help page from my bundle and contains embedded resources (external css, YUI!, images). The only request that comes through is the initial page load, shouldStartLoadWithRequestisn't called for any of the dependencies. So it is curious why your didFinishLoad is called multiple times.

我刚刚在我的一个项目中看到了对所有三个的调用,这些调用从我的包中加载了一个帮助页面并包含嵌入式资源(外部 css、YUI!、图像)。通过的唯一请求是初始页面加载,shouldStartLoadWithRequest不会为任何依赖项调用。所以很好奇为什么你的 didFinishLoad 被多次调用。

Perhaps what you're seeing is due to redirects, or as mentioned, ajax calls within a loaded page. But you at least should be able balance calls to shouldStartLoadand either of the other two delegate functions and be able to determine when the loading is finished.

也许您看到的是由于重定向,或者如前所述,加载页面中的 ajax 调用。但是您至少应该能够平衡shouldStartLoad对其他两个委托函数中的一个的调用,并能够确定加载何时完成。

回答by Scott Densmore

You can do something like this to check when loading is finished. Because you can have a lot of content on the same page you need it.

你可以做这样的事情来检查加载何时完成。因为您可以在需要它的同一页面上拥有大量内容。

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

回答by Vinod Singh

Check this one it so simply and easy way to achieve no need to write too much code:

勾选这个就这么简单简单的实现方式,不需要写太多代码:

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

回答by Cezar

This question is already solved, but I see it lacks an answer that actually explains why multiple calls to webViewDidFinishLoadare actually expected behavior

这个问题已经解决了,但我看到它缺乏一个真正解释为什么多次调用webViewDidFinishLoad实际上是预期行为的答案

The aforementioned method is called every time the webview finishes loading a frame. From the UIWebViewDelegate protocol documentation:

每次 webview 完成加载框架时都会调用上述方法。来自UIWebViewDelegate 协议文档

webViewDidFinishLoad:
Sent after a web view finishes loading a frame.

webViewDidFinishLoad:
在 Web 视图完成加载框架后发送。

In fact, this is also true for all the other methods that comprise the UIWebViewDelegateprotocol.

事实上,对于包含UIWebViewDelegate协议的所有其他方法也是如此。

回答by Yogeesh H T

Try this it will work fine

试试这个它会工作正常

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

回答by Viswanth Chadalawada

This happens because the callback method is called every time a frame is done loading. In order to prevent this set the "suppressesIncrementalRendering" property of the webview to true. this will prevent the webview from rendering until the entire data is loaded into the memory. This did the trick for me

发生这种情况是因为每次完成加载帧时都会调用回调方法。为了防止这种情况,将 webview 的“suppressesIncrementalRendering”属性设置为 true。这将阻止 webview 呈现,直到整个数据加载到内存中。这对我有用

回答by Luis

I have notice something similar and it was a confusion: I have a UITabBarController, it seems to preload all ViewControllerslinked to its tabs on launching the App (in spite of showing just first_Tab_ViewController), so when several tabs have ViewControllerwith WebView their respective webViewDidFinishLoadare called and if I have copied pasted:

我注意到类似的东西,这是一个混乱:我有一个UITabBarController,它似乎ViewControllers在启动应用程序时预加载所有链接到其选项卡(尽管只显示 first_Tab_ViewController),所以当几个选项卡具有ViewControllerWebView 时,它们各自webViewDidFinishLoad被调用,如果我已经复制粘贴了:

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

in several, I get several output in console that appears to be a double calling when they really are single calling in two different UIWebViews.

在几个中,我在控制台中得到几个输出,当他们真的在两个不同的UIWebViews.

回答by nico

You could check the loading and request properties in the webViewDidFinishLoad method

您可以在 webViewDidFinishLoad 方法中检查加载和请求属性

回答by Alfie Hanssen

Possibly related to this issue is a property on UIWebView introduced in iOS6: suppressesIncrementalRendering.

可能与此问题相关的是 iOS6 中引入的 UIWebView 上的一个属性:suppressesIncrementalRendering.