iOS使用WKWebView加载H5时遇到的问题及处理。
前言:
本文章主要针对使用WKWebView加载H5时处理网络慢或没有网络时的优化,比如说,我在加载H5的时候使用第三方加载提示的框架(就是那种转圈圈的,而且加载过程中不给用户点击(为了安全)),当我点击进入H5界面时,假如没有网络了,那个三方控件没办法remove掉,因为在这个两个方法里
- (void)webView:(WKWebView*)webView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation
设置的remove掉视图的方法要等好久才会执行,这样子会给用户很不好的体验。
其实解决这个问题的办法还是很多的,那我是这样解决的:使用延时操作,当请求的时间到达5秒后还是没有请求成功的话,显示一个暂无数据的视图,将WKWebView覆盖在下面,这样即使过了很长时间加载出来了,用户也是看不到的,效果看起来就像是网络崩溃的样子,所以我们要提示用户重新刷新。
其实我还是参考了一位博主的文章,这是他的文章地址:https://www.jianshu.com/p/42ebc145b22a
那思路就是这样子:封装一个NullDataView的视图,继承至UIView,里面放一个UIImageView以及一个UILabel,在ViewController添加WKWebView和封装好的NullDataView,在添加WKWebView的时候别忘了导入库和遵守它的协议哦!在添加的时候一定要记得先添加WKWebView再添加NullDataView,因为我门要的效果就是NullDataView覆盖在WKWebView上面,然后程序第一次执行的时候让NullDataView隐藏,WKWebView显示,然后在使用延时操作,5秒过后,如果请求未成功的话就将NullDataView显示,WKWebView隐藏,并提示用户重新刷新,或者告诉用户网络出了问题。
下面是部分代码:
#import "ViewController.h"
#import "NullDataView.h"
#import
@interface ViewController ()<WKUIDelegate, WKNavigationDelegate>
/**
WKWebView
*/
@property (strong, nonatomic) WKWebView *wbView;
/**
没有数据展示的视图
*/
@property (strong, nonatomic) NullDataView *nullView;
/**
用来判断是否加载完成
*/
@property(nonatomic,assign)BOOL network;
@end
@implementationViewController
#pragma mark 懒加载
- (NullDataView*)nullView {
if(!_nullView) {
_nullView= [[NullDataViewalloc]initWithFrame:self.view.bounds];
}
return _nullView;
}
- (WKWebView*)wbView {
if(!_wbView) {
WKWebViewConfiguration *cf = [[WKWebViewConfiguration alloc] init];
_wbView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:cf];
_wbView.UIDelegate=self;
_wbView.navigationDelegate = self;
}
return _wbView;
}
#pragma mark 系统回调函数
- (void)viewDidLoad {
[super viewDidLoad];
if(@available(iOS11.0, *)) {
self.wbView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}else{
self.edgesForExtendedLayout = UIRectEdgeNone;
}
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURLRequest *qt = [NSURLRequest requestWithURL:url];
[self.wbViewloadRequest:qt];
__weak typeof(self)weakSelf = self;
//耗时操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(weakSelf.network==NO) {
//如果5秒过后未加载成功,在这里可以取消转圈圈的第三方控件,这里就不做演示了,但是显示空视图还是可以的。
self.wbView.hidden=YES;
self.nullView.hidden=NO;
}
});
//添加子视图
[self addSubviews];
}
/**
添加子视图
*/
- (void)addSubviews {
//子视图到父类视图
[self.viewaddSubview:self.wbView];
[self.viewaddSubview:self.nullView];
//第一次加载,隐藏空视图,显示wbView
self.nullView.hidden=YES;
self.wbView.hidden=NO;
}
#pragma mark WKUIDelegate, WKNavigationDelegate
- (void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation {
//加载WKWebView的时候,在这里可以弄一个转圈圈的第三方控件,这里就不做演示了
}
- (void)webView:(WKWebView*)webView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error {
//加载WKWebView失败的时候,在这里可以取消转圈圈的第三方控件,这里就不做演示了
}
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation {
//加载WKWebView完成的时候,在这里可以取消转圈圈的第三方控件,这里就不做演示了
//这里配合延时执行 模拟 加载延时 在规定的时间没有加载完成 就是加载失败
self.network=YES;
}
@end
好了,下面贴出我Demo的地址 :
https://github.com/RegretSF/WKWebViewNetworkLoading
若是有什么问题,还请各位大神多多指教!谢谢!