UIWebView 启动了两次 - IOS
UIWebView started twice - IOS
我正在使用下面的方法添加 ProgressView
,而 UIWebView
正在加载并在完成后将其关闭。
问题是 UIWebView 和 ProgressView 启动了两次,所以当页面加载完成后,只有一个 ProgressView 被关闭,另一个没有。
ViewController.h
#import <UIKit/UIKit.h>
@interface DirectionViewController : UIViewController <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *directionWebView;
@end
ViewController.m
@interface ViewController ()
@property UIColor *yellowColor;
@property MRProgressOverlayView *progressView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.yellowColor =
[UIColor colorWithRed:244.0f/255.0f
green:208.0f/255.0f
blue:63.0f/255.0f
alpha:1.0f];
self.directionWebView.delegate = self;
NSString *urlMap = [NSString stringWithFormat:@"%@%f,%f&zoom=14", @"http://maps.google.com/maps?q=", self.coordLat, self.coordLong];
NSURL *url = [NSURL URLWithString:urlMap];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.directionWebView loadRequest:urlRequest];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"WebView start loading...");
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
}
@end
不知道为什么它会调用两次,但你可以这样做。
if(!self.progressView){
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
[self.progressView show:YES];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
self.progressView = nil;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
可以多次调用此委托方法(例如在重定向的情况下)。所以我建议将您的进度视图初始化代码移动到 viewDidLoad 方法。
- (void)viewDidLoad {
[super viewDidLoad];
//...
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"WebView start loading...");
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[self.progressView dismiss:YES];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
它可能会被多次触发,例如重定向、iframe
加载等。在这里初始化对象很不方便
对其使用Lazy Initialization
设计模式
- (MRProgressOverlayView *)progressView {
if (_progressView) {
_progressView = [... alloc] init];
// ... setup your progressView
}
return _progressView;
}
顺便说一句,您忘记了错误处理:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// You need to stop loading indicator here, right?!
}
第二件事是 - (也许对你来说这没什么大不了的)但通常很难准确确定 UIWebView 何时停止加载(加载所有资源,AJAX 请求等等)
我个人使用类似下面的代码来管理 UIWebView
的 activity 指标 start/stop 行为
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"Webview (%p) starting to load URL: %@", self, request.URL);
self.URL = request.URL;
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[self.spinner startAnimating];
self.webViewLoadingCount++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.webViewLoadingCount--;
if (self.webViewLoadingCount > 0) return;
[self.spinner stopAnimating];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
self.webViewLoadingCount--;
[self.spinner stopAnimating];
// Ignore NSURLErrorDomain error (-999).
if (error.code == NSURLErrorCancelled) return;
// Ignore "Frame Load Interrupted" errors
if (error.code == 102 && [error.domain isEqual:@"WebKitErrorDomain"]) return;
NSLog(@"WebView (%p) experienced an error: %@.", self, [error localizedDescription]);
}
我正在使用下面的方法添加 ProgressView
,而 UIWebView
正在加载并在完成后将其关闭。
问题是 UIWebView 和 ProgressView 启动了两次,所以当页面加载完成后,只有一个 ProgressView 被关闭,另一个没有。
ViewController.h
#import <UIKit/UIKit.h>
@interface DirectionViewController : UIViewController <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *directionWebView;
@end
ViewController.m
@interface ViewController ()
@property UIColor *yellowColor;
@property MRProgressOverlayView *progressView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.yellowColor =
[UIColor colorWithRed:244.0f/255.0f
green:208.0f/255.0f
blue:63.0f/255.0f
alpha:1.0f];
self.directionWebView.delegate = self;
NSString *urlMap = [NSString stringWithFormat:@"%@%f,%f&zoom=14", @"http://maps.google.com/maps?q=", self.coordLat, self.coordLong];
NSURL *url = [NSURL URLWithString:urlMap];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.directionWebView loadRequest:urlRequest];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"WebView start loading...");
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
}
@end
不知道为什么它会调用两次,但你可以这样做。
if(!self.progressView){
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
[self.progressView show:YES];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
self.progressView = nil;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
可以多次调用此委托方法(例如在重定向的情况下)。所以我建议将您的进度视图初始化代码移动到 viewDidLoad 方法。
- (void)viewDidLoad {
[super viewDidLoad];
//...
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:@"Loading ..."];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"WebView start loading...");
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[self.progressView dismiss:YES];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
它可能会被多次触发,例如重定向、iframe
加载等。在这里初始化对象很不方便
对其使用Lazy Initialization
设计模式
- (MRProgressOverlayView *)progressView {
if (_progressView) {
_progressView = [... alloc] init];
// ... setup your progressView
}
return _progressView;
}
顺便说一句,您忘记了错误处理:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// You need to stop loading indicator here, right?!
}
第二件事是 - (也许对你来说这没什么大不了的)但通常很难准确确定 UIWebView 何时停止加载(加载所有资源,AJAX 请求等等)
我个人使用类似下面的代码来管理 UIWebView
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"Webview (%p) starting to load URL: %@", self, request.URL);
self.URL = request.URL;
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[self.spinner startAnimating];
self.webViewLoadingCount++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.webViewLoadingCount--;
if (self.webViewLoadingCount > 0) return;
[self.spinner stopAnimating];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
self.webViewLoadingCount--;
[self.spinner stopAnimating];
// Ignore NSURLErrorDomain error (-999).
if (error.code == NSURLErrorCancelled) return;
// Ignore "Frame Load Interrupted" errors
if (error.code == 102 && [error.domain isEqual:@"WebKitErrorDomain"]) return;
NSLog(@"WebView (%p) experienced an error: %@.", self, [error localizedDescription]);
}