// // TLWebViewController.m // TLChat // // Created by 李伯坤 on 16/2/10. // Copyright © 2016年 李伯坤. All rights reserved. // #import "TLWebViewController.h" #import "UIBarButtonItem+Back.h" #import "WKWebView+Post.h" #define WEBVIEW_NAVBAR_ITEMS_FIXED_SPACE 9 @interface TLWebViewController () @property (nonatomic, strong) WKWebView *webView; @property (nonatomic, strong) UIProgressView *progressView; @property (nonatomic, strong) UIBarButtonItem *backButtonItem; @property (nonatomic, strong) UIBarButtonItem *closeButtonItem; @property (nonatomic, strong) UILabel *authLabel; @end @implementation TLWebViewController - (id)init { if (self = [super init]) { self.useMPageTitleAsNavTitle = YES; self.showLoadingProgress = YES; self.showPageInfo = YES; } return self; } - (id)initWithUrl:(NSString *)urlString { if (self = [self init]) { [self setUrl:urlString]; } return self; } - (id)initWithRequest:(NSURLRequest *)request { if (self = [super init]) { [self loadRequest:request]; } return self; } - (void)loadView { [super loadView]; [self.view addSubview:self.authLabel]; [self.view addSubview:self.webView]; [self.view addSubview:self.progressView]; } - (void)viewDidLoad { [super viewDidLoad]; [self.view setBackgroundColor:RGBAColor(46.0, 49.0, 50.0, 1.0)]; [self.webView.scrollView setBackgroundColor:[UIColor clearColor]]; for (id vc in self.webView.scrollView.subviews) { NSString *className = NSStringFromClass([vc class]); if ([className isEqualToString:@"WKContentView"]) { [vc setBackgroundColor:[UIColor whiteColor]]; break; } } [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL]; [self.webView.scrollView addObserver:self forKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionNew context:NULL]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; } - (void)dealloc { [self.webView removeObserver:self forKeyPath:@"estimatedProgress"]; [self.webView.scrollView removeObserver:self forKeyPath:@"backgroundColor"]; #ifdef DEBUG_MEMERY NSLog(@"dealloc WebVC"); #endif } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height; CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height; CGFloat width = self.view.bounds.size.width; [self.progressView setY:statusBarHeight + navBarHeight]; [self.authLabel setFrame:CGRectMake(20, statusBarHeight + navBarHeight + 13, width - 40, self.authLabel.frame.size.height)]; } #pragma mark - # Public Methods - (void)setUrl:(NSString *)url { if (_url && url && [_url isEqualToString:url]) { return; } _url = url; [self.progressView setProgress:0.0f]; [self.webView loadRequest:[NSURLRequest requestWithURL:TLURL(self.url)]]; } - (void)setShowLoadingProgress:(BOOL)showLoadingProgress { _showLoadingProgress = showLoadingProgress; [self.progressView setHidden:!showLoadingProgress]; } - (void)loadRequest:(NSURLRequest *)request { [self.webView loadRequest:request]; } - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { if (string) { [self.webView loadHTMLString:string baseURL:baseURL]; } } #pragma mark - # Delegate //MARK: WKNavigationDelegate // 开始加载页面 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; } // 开始返回页面内容 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { if (webView.canGoBack) { [self.navigationItem setLeftBarButtonItems:@[[UIBarButtonItem fixItemSpace:-WEBVIEW_NAVBAR_ITEMS_FIXED_SPACE], self.backButtonItem, self.closeButtonItem]]; } } // 加载完成 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; if (self.useMPageTitleAsNavTitle) { [self.navigationItem setTitle:webView.title]; } if (self.showPageInfo) { if (webView.URL.host.length > 0) { [self.authLabel setText:[NSString stringWithFormat:@"网页由 %@ 提供", webView.URL.host]]; } else { [self.authLabel setText:@""]; } [self.authLabel setHeight:[self.authLabel sizeThatFits:CGSizeMake(self.authLabel.width, MAXFLOAT)].height]; } } // 加载失败 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; [TLUIUtility showAlertWithTitle:nil message:[error description]]; } // 页面跳转处理 // 接收到服务器跳转请求之后调用 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation { } // 在收到响应后,决定是否跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { decisionHandler(WKNavigationResponsePolicyAllow); } // 在发送请求之前,决定是否跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSString *urlString = navigationAction.request.URL.absoluteString; if ([urlString hasPrefix:@"itms-apps://itunes.apple.com"] || [urlString hasPrefix:@"https://itunes.apple.com"] || [urlString hasPrefix:@"itms-services:"] || [urlString hasPrefix:@"tel:"] || [urlString hasPrefix:@"mailto:"] || [urlString hasPrefix:@"mqqwpa:"]) { [[UIApplication sharedApplication] openURL:navigationAction.request.URL]; decisionHandler(WKNavigationActionPolicyCancel); } else { decisionHandler(WKNavigationActionPolicyAllow); } } //MARK: WKUIDelegate // web界面中有弹出警告框 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(nonnull NSString *)message initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(void))completionHandler { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { completionHandler(); }]]; [self presentViewController:alertController animated:YES completion:^{}]; } // web界面中有确认框 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(nonnull NSString *)message initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(BOOL))completionHandler { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { completionHandler(YES); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){ completionHandler(NO); }]]; [self presentViewController:alertController animated:YES completion:^{}]; } // web界面中有弹出输入框 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(nonnull NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(NSString * _Nullable))completionHandler { completionHandler(@"Client Not handler"); } #pragma mark - # Event Response - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (self.showLoadingProgress && [keyPath isEqualToString:@"estimatedProgress"] && object == self.webView) { [self.progressView setAlpha:1.0f]; [self.progressView setProgress:self.webView.estimatedProgress animated:YES]; if(self.webView.estimatedProgress >= 1.0f) { [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{ [self.progressView setAlpha:0.0f]; } completion:^(BOOL finished) { [self.progressView setProgress:0.0f animated:NO]; }]; } } else if ([keyPath isEqualToString:@"backgroundColor"] && object == self.webView.scrollView) { UIColor *color = [change objectForKey:@"new"]; if (!CGColorEqualToColor(color.CGColor, [UIColor clearColor].CGColor)) { [object setBackgroundColor:[UIColor clearColor]]; } } } - (void)navBackButotnDown { if (self.webView.canGoBack) { [self.webView goBack]; } else { [self.navigationController popViewControllerAnimated:YES]; } } - (void)navCloseButtonDown { [self.navigationController popViewControllerAnimated:YES]; } #pragma mark - # Getters - (WKWebView *)webView { if (_webView == nil) { _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, STATUSBAR_HEIGHT + NAVBAR_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - STATUSBAR_HEIGHT - NAVBAR_HEIGHT)]; [_webView setAllowsBackForwardNavigationGestures:YES]; [_webView setNavigationDelegate:self]; [_webView setUIDelegate:self]; [_webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight]; } return _webView; } - (UIProgressView *)progressView { if (_progressView == nil) { _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, NAVBAR_HEIGHT + STATUSBAR_HEIGHT, SCREEN_WIDTH, 10.0f)]; [_progressView setTransform:CGAffineTransformMakeScale(1.0f, 2.0f)]; [_progressView setProgressTintColor:RGBAColor(2.0, 187.0, 0.0, 1.0f)]; [_progressView setTrackTintColor:[UIColor clearColor]]; [_progressView setProgress:0]; } return _progressView; } - (UIBarButtonItem *)backButtonItem { if (_backButtonItem == nil) { _backButtonItem = [[UIBarButtonItem alloc] initWithBackTitle:@"返回" target:self action:@selector(navBackButotnDown)]; } return _backButtonItem; } - (UIBarButtonItem *)closeButtonItem { if (_closeButtonItem == nil) { _closeButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(navCloseButtonDown)]; } return _closeButtonItem; } - (UILabel *)authLabel { if (_authLabel == nil) { _authLabel = [[UILabel alloc] init]; [_authLabel setFont:[UIFont systemFontOfSize:12.0f]]; [_authLabel setTextAlignment:NSTextAlignmentCenter]; [_authLabel setTextColor:[UIColor grayColor]]; [_authLabel setNumberOfLines:0]; } return _authLabel; } @end