|
|
|
//
|
|
|
|
// 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
|