经过长时间休息后,我又开始进行ios开发了。考虑到这一点,我下载了最新版本的XCode(5.02)并开始编写以ios7为目标的应用程序。在我向我的应用添加“webView页面”之前,一切都很顺利。我天真地期待UIWebView像Safari中的页面一样工作,但事实并非如此。最缺少的是在页面加载时对用户完全没有反馈。即网络活动指示器根本不显示,并且在页面加载时没有显示进度条。所以我想你只需要手动添加它们。这不应该太难,不是吗?
几天后,我的工作得很好,但我对结果并不满意。我花了相当多的调试和实验来获得我现在的位置。我想我的问题是“有什么办法可以改善我的方法吗?”而且,也许,“我应该向Apple报告加载和请求财产问题并要求他们修复它们吗?”
最初我在互联网上查找了这个问题的解决方案,关于它的stackoverflow有很多问题,但似乎没有人真正破解它。一些建议的方法:
最后我决定使用4.和5.但这很棘手,因为:
第一个问题可以通过计算开始和结束来确定,确保计算的进度百分比仅增加,并且只在最后一个请求完成时关闭网络指示器。
第二个问题更难以解决。 UIWebView有两个原则上可用于执行此操作的属性(加载和请求),但它们似乎以神秘的方式工作。我在这里找到的一些答案和评论表明,loading属性永远不会更新,但请求就是。这最初对我有意义,因为页面永远不会真正停止加载(它们可能具有动态内容),因此有意义的是加载属性只会告诉您Web视图是否正在主动加载内容(即,如果已调用loadRequest并且stopLoading还没有“T)。
然而,至少在ios7上,它实际上是以相反的方式工作。 request属性永远不会更新,因此您无法使用request属性来确定视图是否已完成加载所有内容(即通过检查已完成的请求是否为初始请求)。虽然loading属性已更新,但在页面完全加载时它确实设置为NO。这有很大帮助,但我注意到动态内容(例如页面广告)会导致加载重置为YES,因此处理它仍然有点棘手。
第三个问题不是问题,除了我观察到webView内部:didFailLoadWithError,loading属性总是设置为NO。但是,这似乎是一个临时状态,如果您愿意,可以忽略错误并等待在webViewDidFinishLoad中将加载设置为NO。由于请求属性未更新,因此无法知道它是否是失败的初始请求或其中一个子请求(您可能会或可能不关心)。所以我决定采用一种允许程序员选择他们想要的行为的解决方案。
如果出现以下情况会更容易:
这是我在webView的视图控制器中的代码:
- (void)resetProgress {
framesToLoad = 0;
framesLoaded = 0;
currentProgress = 0.0f;
}
- (void)resetForNewPage {
// Reset progress
[self resetProgress];
// Monitor the page load
monitorProgress = YES;
// Keep going if errors occur
// completeIfError = NO;
// Stop updates if an error occurs
completeIfError = YES;
}
- (void)webViewLoaded {
[self resetProgress];
[entryProgressView setProgress: 0.0f animated: YES];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Reset state for new page load
[self resetForNewPage];
// Load the page
NSURLRequest *entryRequest = [NSURLRequest requestWithURL:entryURL];
[entryWebView loadRequest:entryRequest];
}
-(void)viewWillDisappear:(BOOL)animated {
[entryWebView stopLoading];
entryWebView.delegate = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
// Reset state for new page load
[self resetForNewPage];
}
return YES;
}
-(void)webViewDidStartLoad:(UIWebView *)webView {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
if (!monitorProgress) {
return;
}
// Increment frames to load counter
framesToLoad++;
}
-(void)webViewDidFinishLoad:(UIWebView *) webView {
if (!monitorProgress) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
return;
}
// Increment frames loaded counter
framesLoaded++;
// Update progress display
float newProgress = ((float) framesLoaded) / framesToLoad;
if (newProgress > currentProgress) {
currentProgress = newProgress;
[entryProgressView setProgress: newProgress animated: YES];
}
// Finish progress updates if loading is complete
if (!webView.loading) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
monitorProgress = NO;
[entryProgressView setProgress: 1.0 animated: YES];
[self performSelector:@selector(webViewLoaded) withObject: nil afterDelay: 1.0];
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if (!monitorProgress) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
return;
}
// Increment frames loaded counter
framesLoaded++;
// Update progress display
float newProgress = ((float) framesLoaded) / framesToLoad;
if (newProgress > currentProgress) {
currentProgress = newProgress;
[entryProgressView setProgress: newProgress animated: YES];
}
// Finish progress updates if required
if (completeIfError) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
monitorProgress = NO;
[entryProgressView setProgress: 1.0 animated: YES];
[self performSelector:@selector(webViewLoaded) withObject: nil afterDelay: 1.0];
}
}