// // WebViewController.m // watch // // Created by xTT on 2017/9/3. // Copyright © 2017年 xTT. All rights reserved. // #import "WebViewController.h" #import @interface WebViewController() /// 右侧的选项 容器View @property (nonatomic, strong) UIView *webOptionView; /// 进度条 @property (nonatomic, strong) UIProgressView* progressView; /// 当前链接 @property (nonatomic, strong) NSString* currentURLString; /// 第一次加载完成 @property (nonatomic, assign) BOOL isFristLoadFinish; /** 隐藏导航栏时有的返回按钮 */ @property (nonatomic, strong) UIButton *backBtn; @end @implementation WebViewController - (WKWebView *)myWebView{ if (!_myWebView) { _myWebView = [[WKWebView alloc] init]; [self.view addSubview:_myWebView]; [_myWebView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.view); make.top.equalTo(self.view).offset(iPhoneX_NavHeight); make.bottom.equalTo(self.view.mas_bottom); }]; } return _myWebView; } -(UIProgressView *)progressView{ if(!_progressView){ _progressView = [[UIProgressView alloc] init]; _progressView.progressTintColor = mainColor; [self.view addSubview:_progressView]; [_progressView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_offset(0); make.left.mas_offset(0); make.right.mas_offset(0); make.height.mas_offset(3); }]; } return _progressView; } -(BOOL)prefersStatusBarHidden{ if(self.isHiddenNavigationBar){ return YES; } return NO; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; if(self.isHiddenNavigationBar){ [self.navigationController.navigationBar setHidden:YES]; } } //-(BOOL)prefersStatusBarHidden{ // if(self.isHiddenNavigationBar){ // return YES; // }else{ // return NO; // } //} //进入显示页面 -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; if (self.isShowMoreOperations){ // 禁用返回手势 if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { self.navigationController.interactivePopGestureRecognizer.enabled = NO; } } } //退出页面 -(void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; if(self.isHiddenNavigationBar){ [[UIApplication sharedApplication] setStatusBarHidden:NO]; [self.navigationController.navigationBar setHidden:NO]; } //移除观察者 @try { [_myWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))]; } @catch (NSException *exception) { NSLog(@"RemoveObserver estimatedProgress ERROR!"); } // [_webView removeObserver:self forKeyPath:NSStringFromSelector(@selector(title))]; if (self.isShowMoreOperations){ // 开启返回手势 if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { self.navigationController.interactivePopGestureRecognizer.enabled = YES; } } } //kvo 监听进度 必须实现此方法 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == _myWebView) { NSLog(@"网页加载进度 = %f",_myWebView.estimatedProgress); self.progressView.progress = _myWebView.estimatedProgress; if (_myWebView.estimatedProgress >= 1.0f) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.progressView.progress = 0; self.progressView.hidden = YES; }); }else{ self.progressView.hidden = NO; } } else if([keyPath isEqualToString:@"title"] && object == _myWebView){ if (self.isShowMoreOperations) { } } else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)viewDidLoad{ [super viewDidLoad]; if(self.isShowMoreOperations){ UIBarButtonItem *webOperationBtn = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon_operation"] style:UIBarButtonItemStylePlain target:self action:@selector(webOperationAction:)]; UIBarButtonItem *closeBtn = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon_close"] style:UIBarButtonItemStylePlain target:self action:@selector(closeWebAction:)]; //右键复制连接或者在浏览器打开 self.navigationItem.rightBarButtonItems = @[webOperationBtn,closeBtn]; } //添加监测网页加载进度的观察者 [self.myWebView addObserver:self forKeyPath:@"estimatedProgress" options:0 context:nil]; //添加监测网页标题title的观察者 [self.myWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; if(self.content){ [self.myWebView loadHTMLString:self.content baseURL:nil]; }else{ [self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.url]]]; } self.myWebView.navigationDelegate = self; if(self.isHiddenNavigationBar){ //创建返回按钮 // _backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; // _backBtn.frame = CGRectMake(14, 40, 30, 30); // [_backBtn setBackgroundImage:[UIImage imageNamed:@"icon_return_black"] forState:0]; // [_backBtn addTarget:self action:@selector(goBack:) forControlEvents:UIControlEventTouchUpInside]; // [self.view addSubview:_backBtn]; } } - (void)openScheme:(NSString *)scheme { UIApplication *application = [UIApplication sharedApplication]; NSURL *URL = [NSURL URLWithString:scheme]; //iOS 10 以后 if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) { //1 如果这个要打开的URL有效,并且在应用中配置它布尔值为true(YES)时才可以打开,否则打不开 // NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly : @YES}; //2 此时与openURL功能相似 NSDictionary *options =@{}; [application openURL:URL options:options completionHandler:^(BOOL success) { NSLog(@"Open %@: %d",scheme,success); }]; } else { if ([application canOpenURL:URL]) { BOOL success = [application openURL:URL]; NSLog(@"Open %@: %d",scheme,success); } } } -(void)goBack:(id)sender{ if(self.isShowMoreOperations){ if (self.myWebView.canGoBack) { [self.myWebView goBack]; }else{ [self.navigationController popViewControllerAnimated:YES]; } }else{ [super goBack:sender]; } } - (void)closeWebAction:(id)sender{ [self.navigationController popViewControllerAnimated:YES]; } - (void)webOperationAction:(UIBarButtonItem*)sender{ if(self.isFristLoadFinish == NO){ return; } //如果还没加载完成,不能打开 if(!_webOptionView){ CGFloat aWidth = 180; _webOptionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)]; _webOptionView.backgroundColor = RGBA(2, 1, 6, 0.4); _webOptionView.userInteractionEnabled = YES; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hiddenWebOptionAction:)]; [_webOptionView addGestureRecognizer:tap]; UIWindow *win = [UIApplication sharedApplication].keyWindow; [win addSubview:_webOptionView]; UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(ScreenWidth-aWidth-25, getRectNavAndStatusHight - 20, aWidth, 90)]; contentView.layer.cornerRadius = 5; contentView.layer.masksToBounds = YES; contentView.backgroundColor = [UIColor whiteColor]; [_webOptionView addSubview:contentView]; UIButton *copBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [copBtn setImage:[UIImage imageNamed:@"icon_copylink"] forState:0]; [copBtn setTitle:@"复制连接" forState:0]; copBtn.frame = CGRectMake(0, 0, aWidth, 45); copBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; [copBtn setTitleColor:RGB(52, 52, 52) forState:0]; copBtn.titleLabel.font = DefineFontSize; copBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0); copBtn.titleEdgeInsets =UIEdgeInsetsMake(0, 15+15, 0, 0); [contentView addSubview:copBtn]; [copBtn addTarget:self action:@selector(copyLinkAction:) forControlEvents:UIControlEventTouchUpInside]; UIButton *openWebBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [openWebBtn setImage:[UIImage imageNamed:@"icon_browser_open"] forState:0]; [openWebBtn setTitleColor:RGB(52, 52, 52) forState:0]; [openWebBtn setTitle:@"在浏览器中打开" forState:0]; openWebBtn.titleLabel.font = DefineFontSize; openWebBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0); openWebBtn.titleEdgeInsets =UIEdgeInsetsMake(0, 15+15, 0, 0); openWebBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; openWebBtn.frame = CGRectMake(0, 45, aWidth, 45); [contentView addSubview:openWebBtn]; [openWebBtn addTarget:self action:@selector(openLinkWithSystemWeb:) forControlEvents:UIControlEventTouchUpInside]; } _webOptionView.hidden = !_webOptionView.hidden; } - (void)hiddenWebOptionAction:(id)sender{ if(_webOptionView){ _webOptionView.hidden = YES; } } /// 复制连接 - (void)copyLinkAction:(UIButton*)sender{ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; if(self.currentURLString.length > 0){ pasteboard.string = self.currentURLString; xLog(@"复制连接到剪贴板了...:%@",self.currentURLString); [UICommon MessageSuccessText:@"链接已经成功复制到剪贴板" isImg:YES]; [self hiddenWebOptionAction:nil]; } } /// 打开浏览器 - (void)openLinkWithSystemWeb:(UIButton*)sender{ if(_currentURLString.length > 0){ // IOS11 以下的 if([[[UIDevice currentDevice] systemVersion] doubleValue] < 10.0){ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_currentURLString]]; }else{ // iOS 11 以上 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_currentURLString] options:@{} completionHandler:^(BOOL success) { xLog(@"success: %d",success); }]; } } [self hiddenWebOptionAction:nil]; } // 页面开始加载时调用 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { } // 页面加载失败时调用 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { [self.progressView setProgress:0.0f animated:NO]; } // 当内容开始返回时调用 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { } // 页面加载完成之后调用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { // [self getCookie]; self.currentURLString = webView.URL.absoluteURL.absoluteString; self.isFristLoadFinish = YES; xLog(@"页面加载完成时的连接:%@",self.currentURLString); } //提交发生错误时调用 - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { [self.progressView setProgress:0.0f animated:NO]; } // 接收到服务器跳转请求即服务重定向时之后调用 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation { } // 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSString * urlStr = navigationAction.request.URL.absoluteString; xLog(@"发送跳转请求:%@",urlStr); NSString * toJumpURL = @""; if ([urlStr containsString:@"apps.apple.com"] || [urlStr containsString:@"itunes.apple.com"]) { toJumpURL = [urlStr stringByReplacingOccurrencesOfString:@"https:" withString:@"itms-apps:"]; }else if (![urlStr hasPrefix:@"https://"] && ![urlStr hasPrefix:@"http://"]){ // 不含 https:// 和 http:// 的都跳转 toJumpURL = urlStr; } if(toJumpURL.length > 0){ if([toJumpURL containsString:@"://"]){ xLog(@"只有包含 : < :// > 的才控制跳转浏览器: %@", urlStr); // IOS11 以下的 if([[[UIDevice currentDevice] systemVersion] doubleValue] < 11.0){ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:toJumpURL]]; }else{ // iOS 11 以上 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:toJumpURL] options:@{} completionHandler:^(BOOL success) { xLog(@"success: %d",success); }]; } } } //自己定义的协议头 // NSString *htmlHeadString = @"github://"; // if([urlStr hasPrefix:htmlHeadString]){ // UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"通过截取URL调用OC" message:@"你想前往我的Github主页?" preferredStyle:UIAlertControllerStyleAlert]; // [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { // }])]; // [alertController addAction:([UIAlertAction actionWithTitle:@"打开" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // NSURL * url = [NSURL URLWithString:[urlStr stringByReplacingOccurrencesOfString:@"github://callName_?" withString:@""]]; // [[UIApplication sharedApplication] openURL:url]; // }])]; // [self presentViewController:alertController animated:YES completion:nil]; // decisionHandler(WKNavigationActionPolicyCancel); // }else{ decisionHandler(WKNavigationActionPolicyAllow); // } } // 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSString * urlStr = navigationResponse.response.URL.absoluteString; NSLog(@"当前跳转地址:%@",urlStr); //允许跳转 decisionHandler(WKNavigationResponsePolicyAllow); //不允许跳转 //decisionHandler(WKNavigationResponsePolicyCancel); } //需要响应身份验证时调用 同样在block中需要传入用户身份凭证 //- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{ // //用户身份信息 // NSURLCredential * newCred = [[NSURLCredential alloc] initWithUser:@"user123" password:@"123" persistence:NSURLCredentialPersistenceNone]; // //为 challenge 的发送方提供 credential // [challenge.sender useCredential:newCred forAuthenticationChallenge:challenge]; // completionHandler(NSURLSessionAuthChallengeUseCredential,newCred); //} //进程被终止时调用 - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{ } @end