123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- //
- // LMWebviewController.m
- // LMWebview
- //
- // Created by Leesim on 2018/6/25.
- // Copyright © 2018年 LiMing. All rights reserved.
- //
- #import "LMWebviewController.h"
- #import <WebKit/WebKit.h>
- #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 ()<WKNavigationDelegate,WKUIDelegate,UIGestureRecognizerDelegate>
- @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
|