You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

414 lines
16 KiB

//
// WebViewController.m
// watch
//
// Created by xTT on 2017/9/3.
// Copyright © 2017年 xTT. All rights reserved.
//
#import "WebViewController.h"
#import <Photos/Photos.h>
@interface WebViewController()<WKNavigationDelegate>
/// 右侧的选项 容器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<NSKeyValueChangeKey,id> *)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