【问题标题】:UIWebView started twice - IOSUIWebView 启动两次 - IOS
【发布时间】:2016-03-23 09:24:32
【问题描述】:

我正在使用以下内容添加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

【问题讨论】:

    标签: ios objective-c uiwebview uiprogressview uiwebviewdelegate


    【解决方案1】:

    不知道为什么它会调用两次,但你可以这样做。

    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;
    }
    

    【讨论】:

    • 感谢您的回答@KDeogharkar
    【解决方案2】:
    -(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]);
    }
    

    【讨论】:

      【解决方案3】:
      -(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];
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-09
        • 1970-01-01
        • 2017-05-30
        • 1970-01-01
        相关资源
        最近更新 更多