// // LMWebviewController.m // LMWebview // // Created by Leesim on 2018/6/25. // Copyright © 2018年 LiMing. All rights reserved. // #import "LMWebviewController.h" #import #define NAV_HEIGHT (([[UIApplication sharedApplication] statusBarFrame].size.height)+44.0f) #define LMRGBAColor(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a] @interface LMWebviewController () @property (nonatomic,strong) WKWebView * webview; @property (nonatomic,strong) UIBarButtonItem * customBackBarItem; @property (nonatomic,strong) UIBarButtonItem * closeButtonItem; @property (nonatomic,strong) UIBarButtonItem* refreshBarItem; @property (nonatomic,strong) UIView * progressGetView; @property (nonatomic,strong) UIView * errorShowView; //为了修复侧滑手势在webview上响应 @property (nonatomic,assign) id delegate; //注入方法名 用于接受JS调用原生方法 让Web端掉用iOS端代码 @property (nonatomic,strong) WKWebViewConfiguration *webConfig; @end @implementation LMWebviewController //由于,手动设置了导航栏左按钮,因此我们会发现系统自带的侧滑返回功能失效了,为了网页所在视图控制器的侧滑返回功能可实现,需要再修复其失效的问题。 #pragma mark - 让自定义的导航栏左侧按钮支持侧滑手势的处理 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.navigationController.viewControllers.count > 1) { //记录原来的代理 self.delegate = self.navigationController.interactivePopGestureRecognizer.delegate; //修复手势操作代理 self.navigationController.interactivePopGestureRecognizer.delegate = self; } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //把手势代理在传递给原来的代理对象 self.navigationController.interactivePopGestureRecognizer.delegate = self.delegate; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.webview]; [self.refreshBarItem class]; [self.view addSubview:self.progressGetView]; [self.view addSubview:self.errorShowView]; //更新左侧按钮 [self updateNavigationItems]; } -(void)dealloc{ //移除观察者在离开界面的时候 [self.webview removeObserver:self forKeyPath:@"estimatedProgress"]; [self.webview removeObserver:self forKeyPath:@"title"]; } #pragma mark - delegate or observer // 页面加载完成之后调用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { //判断左侧按钮状态 [self updateNavigationItems]; } // 页面加载失败时调用 开始加载后失败 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { self.title = @"加载失败"; //加载失败时 [self showLoadErrorView]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"estimatedProgress"]) { if (object == self.webview) { self.progressGetView.hidden = NO; [UIView animateWithDuration:0.1 delay:0.1 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.progressGetView.frame =CGRectMake(0,NAV_HEIGHT,SCREEN_WIDTH*self.webview.estimatedProgress, 3); } completion:nil]; //下面动画是为了防止加载进度在快速请求另外的网页的时候 //出现进度条回缩的问题 if(self.webview.estimatedProgress >= 1.0f) { [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{ } completion:^(BOOL finished) { self.progressGetView.frame =CGRectMake(0,NAV_HEIGHT,0, 3); self.progressGetView.hidden = YES; }]; } } }else if ([keyPath isEqualToString:@"title"]) { if (object == self.webview) { self.title = self.webview.title; } } } //两个手势代理是为了让界面响应侧滑手势 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { return self.navigationController.viewControllers.count > 1; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return self.navigationController.viewControllers.count > 1; } #pragma mark - pravite method -(void)setUrlString:(NSString *)urlString{ _urlString = urlString; NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; [self.webview loadRequest:request]; } //更新左侧按钮 -(void)updateNavigationItems{ self.errorShowView.hidden = YES; if (self.webview.canGoBack) { [self.navigationItem setLeftBarButtonItems:@[self.customBackBarItem,self.closeButtonItem] animated:NO]; }else{ self.navigationController.interactivePopGestureRecognizer.enabled = YES; [self.navigationItem setLeftBarButtonItems:@[self.customBackBarItem]]; } } -(void)customBackItemClicked{ //如果可以返回 则返回网页上一级 if (self.webview.goBack) { [self.webview goBack]; }else{ [self closeItemClicked]; } } -(void)closeItemClicked{ //移除js监控 要在pop界面之前 不然会内存泄露 //[self popControllerDealloc]; [self.navigationController popViewControllerAnimated:YES]; } -(void)refreshClicked{ [self.webview reload]; self.errorShowView.hidden = YES; } -(void)errorRefreshClick{ [self.webview reload]; self.errorShowView.hidden = YES; } //当加载网页失败后 展示加载失败界面 - (void)showLoadErrorView{ self.errorShowView.hidden = NO; } #pragma mark - lazy load -(UIBarButtonItem *)customBackBarItem{ if (!_customBackBarItem) { //自定义左侧返回按钮 _customBackBarItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nav_btn_back_black"] style:UIBarButtonItemStylePlain target:self action:@selector(customBackItemClicked)]; } return _customBackBarItem; } -(UIBarButtonItem*)closeButtonItem{ if (!_closeButtonItem) { _closeButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_close"] style:UIBarButtonItemStylePlain target:self action:@selector(closeItemClicked)]; [_closeButtonItem setImageInsets:UIEdgeInsetsMake(0, -8, 0, 0)]; } return _closeButtonItem; } -(UIBarButtonItem *)refreshBarItem{ if (!_refreshBarItem) { _refreshBarItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_fresh"] style:UIBarButtonItemStylePlain target:self action:@selector(refreshClicked)]; self.navigationItem.rightBarButtonItem = _refreshBarItem; } return _refreshBarItem; } -(WKWebView *)webview{ if (!_webview) { _webview = [[WKWebView alloc]initWithFrame:CGRectMake(0, NAV_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT-NAV_HEIGHT)]; _webview.navigationDelegate = self; _webview.UIDelegate = self; //侧滑返回上层 _webview.allowsBackForwardNavigationGestures = YES; //观察进度变化 [_webview addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld context:NULL]; //观察网页标题 [_webview addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL]; } return _webview; } -(UIView *)progressGetView { if (!_progressGetView) { _progressGetView = [[UIView alloc]init]; _progressGetView.frame =CGRectMake(0, NAV_HEIGHT,0 , 3); _progressGetView.backgroundColor = LMRGBAColor(67, 138, 230, 1); } return _progressGetView; } -(UIView *)errorShowView{ if (!_errorShowView) { _errorShowView = [[UIView alloc]init]; _errorShowView.backgroundColor = [UIColor whiteColor]; _errorShowView.frame = CGRectMake(0, NAV_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT-NAV_HEIGHT); UIButton * refreshButton = [[UIButton alloc]init]; refreshButton.bounds = CGRectMake(0, 0, 120, 44); refreshButton.layer.masksToBounds = YES; refreshButton.layer.cornerRadius = 22; refreshButton.layer.borderColor = [UIColor blackColor].CGColor; refreshButton.layer.borderWidth = 1; [refreshButton setTitle:@"刷新" forState:UIControlStateNormal]; [refreshButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; refreshButton.titleLabel.font = [UIFont boldSystemFontOfSize:17]; [refreshButton addTarget:self action:@selector(errorRefreshClick) forControlEvents:UIControlEventTouchUpInside]; [_errorShowView addSubview:refreshButton]; refreshButton.center = CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2-NAV_HEIGHT+22+80); UILabel * showLabel = [[UILabel alloc]init]; showLabel.numberOfLines = 0; showLabel.font = [UIFont systemFontOfSize:16]; showLabel.textColor = LMRGBAColor(0, 0, 0, 0.48); showLabel.text =@"当前网络状态不佳,您可以尝试点击下方按钮刷新重试O~"; showLabel.bounds = CGRectMake(0, 0, SCREEN_WIDTH-88, 1); [showLabel sizeToFit]; [_errorShowView addSubview:showLabel]; showLabel.frame =CGRectMake(44, CGRectGetMinY(refreshButton.frame)-60-showLabel.bounds.size.height, showLabel.bounds.size.width, showLabel.bounds.size.height); UILabel * errorLabel = [[UILabel alloc]init]; errorLabel.font = [UIFont boldSystemFontOfSize:18]; errorLabel.textColor = LMRGBAColor(0, 0, 0, 0.8); errorLabel.text =@"很抱歉,加载失败了"; errorLabel.textAlignment = NSTextAlignmentCenter; [_errorShowView addSubview:errorLabel]; errorLabel.frame =CGRectMake(0, CGRectGetMinY(showLabel.frame)-20-18, SCREEN_WIDTH, 18); _errorShowView.hidden = YES; } return _errorShowView; } @end