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
UIWebView didFinishLoading fires multiple times
提问by Ben Scheirman
I have some code that needs to run after the a UIWebView
finishes loading a document. For that I've set the UIWebView
's delegate to my controller, and implemented the webViewDidFinishLoading
method.
我有一些代码需要在 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, shouldStartLoadWithRequest
isn'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 shouldStartLoad
and 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 webViewDidFinishLoad
are 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 UIWebViewDelegate
protocol.
事实上,对于包含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 ViewControllers
linked to its tabs on launching the App (in spite of showing just first_Tab_ViewController), so when several tabs have ViewController
with WebView their respective webViewDidFinishLoad
are called and if I have copied pasted:
我注意到类似的东西,这是一个混乱:我有一个UITabBarController
,它似乎ViewControllers
在启动应用程序时预加载所有链接到其选项卡(尽管只显示 first_Tab_ViewController),所以当几个选项卡具有ViewController
WebView 时,它们各自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
.