WKWebView的小使用

WKWebView.14年就出来了.用的少.并不是很熟练.听说性能比UIWebView好很多.将内核啥的集成了..就是牛X了
直接谈使用吧.

@property (nonatomic, strong) WKWebView *webView; @property (nonatomic, strong) UIProgressView *progressView;

self.webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - 46)]; self.webView.navigationDelegate = self; self.webView.UIDelegate = self; [self.webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [self.webView setMultipleTouchEnabled:YES]; [self.webView setAutoresizesSubviews:YES]; [self.webView.scrollView setAlwaysBounceVertical:YES]; self.webView.scrollView.delegate = self;//监听偏移值. [self.webView.scrollView addSubview:self.indicatorView];//自己写的 [self.webView.scrollView setContentOffset:CGPointMake(0, 100)]; [self.webView setAllowsBackForwardNavigationGestures:true];//侧滑返回webView的上一级

就是这么实在. 可以直接拷贝使用

几个代理方法.
页面开始加载的时候调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{}

当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { //这里处理返回按钮.默.然后根据webView加载情况判断是否显示或隐藏. self.backButton.hidden = !webView.canGoBack; }
// 页面加载完成之后调用-->比较多的处理在这里操作.
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { [self reloadView]; [self.webView.scrollView setContentOffset:CGPointMake(0, 0)]; if ( self.isLoad == YES) { [self hideHUD]; } }
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation { [self hideHUD]; }

添加观察者.监听title.加载进度.还有一个下拉偏移值(这个是做刷新准备的.也可以使用self.webView.scrollView的偏移代理做.本来这个不需要的.如果有网的情况.是会自动加载出来的.项目经理说有时候刷不出来了,那就按照他的意思,加一个刷新效果.下面介绍思路)

[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];`

[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];`

[self.webView.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew  context:nil];`

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"estimatedProgress"]) {//监听进度 if (object == self.webView) { [self.progressView setAlpha:1.0f]; [self.progressView setProgress:self.webView.estimatedProgress animated:YES]; if(self.webView.estimatedProgress >= 1.0f) { [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{ [self.progressView setAlpha:0.0f]; } completion:^(BOOL finished) { [self.progressView setProgress:0.0f animated:NO]; }]; } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } else if ([keyPath isEqualToString:@"title"])//监听标题 { if (object == self.webView) { if ([self.webView.title fq_IsEqualToString:@"综合"]|| [self.webView.title fq_IsEqualToString:@"活动"]|| [self.webView.title fq_IsEqualToString:@"产品"]|| [self.webView.title fq_IsEqualToString:@"博客"]) { self.title = GETLANGUAGES(self.webView.title, nil); }else{ self.title = self.webView.title; } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } else if(object == self.webView.scrollView && [keyPath isEqualToString:@"contentOffset"]){//监听偏移值.我是为了做刷新处理. CGPoint offset = [change[@"new"] CGPointValue]; self.indicatorView.progress = fabs(offset.y) / 100.0; if (!fabs(offset.y)) { [self.indicatorView stopAnimation]; } if (-offset.y >= 100) { self.webBackView.frame = CGRectMake(0,0, self.view.bounds.size.width, 100); self.webBackView.alpha = 1.0f; } }else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } }

目前没有什么js与oc交互.因为全部是url跳转的.所以我的做法是拦截url.然后做有网没网提示.或者对应的跳转处理.
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{}

这里说一下给webView刷新界面的思路:
1.首先创建一个View.添加到self.view上面.
2.然后当webView下拉到一定层度的时候.我们根据contentOffset的y值来判断是否需要刷新了.前面有监听到偏移值contentOffset
3.比较难实现的就是.下拉让其停顿2s以后,再让webView自动还原到原来的位置,如果还是在观察者里面去更改webView的contentOffset这样就会循环引用
4.我的解决方法是在scrollView的代理里面做一个判断和操作.让整个webview向下偏移.然后让我们添加在self.view上面的视图显示.并且在上面添加一个动画效果.菊花什么.也可以是文字"正在加载系列",刷新界面就很简单了.重新加载url即可.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{ //如果scrollView的一个值达到多少. self.indicatorView.alpha = 1.0f; if((scrollView.contentOffset.y > 0) && self.webView.frame.origin.y != 0){ self.webBackView.alpha= 0.0f; self.webView.frame = CGRectMake(0, 100-scrollView.contentOffset.y, screen_width,self.view.bounds.size.height - 46); [self.webView.scrollView setContentOffset:CGPointMake(0,scrollView.contentOffset.y)]; } }

这个是为了防止部分网页可以缩放的处理
-(void)scrollViewDidZoom:(UIScrollView *)scrollView { self.webBackView.alpha = 0.0f; }

主要是这个方法
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ if (-scrollView.contentOffset.y >= 100) { self.indicatorView.alpha = 0.0f; [UIView animateWithDuration:0.5 animations:^{ self.webView.frame = CGRectMake(0, 100, screen_width,self.view.bounds.size.height - 46); }completion:^(BOOL finished) { self.webBackView.frame = CGRectMake(0, 0, screen_width, 100); [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlStr]]]; }]; //两秒钟以后.执行另一个方法.让他还远 [self performSelector:@selector(reloadView) withObject:nil afterDelay:2.0]; }else{ } }

开始下拉效果.png

下拉结束结束.png

其实就是两层view.一个添加在webView的scrollView上面.让其layer偏移到其上面.跟随一起移动即可,
另外一个View添加在self.view上面

如果有什么更好的方式给webView刷新界面.可以共同学习.

推荐阅读更多精彩内容