简介
UIWebView
源于iOS2
,WKWebView
从iOS8
才有,毫无疑问WKWebView
将逐步取代笨重的UIWebView
。WKWebView
只能用代码创建,而且自身就支持了右滑返回手势allowsBackForwardNavigationGestures
和加载进度estimatedProgress
等一些UIWebView
不具备却非常好用的属性。通过简单的测试即可发现UIWebView占用过多内存,且内存峰值更是夸张。WKWebView
网页加载速度也有提升,但是并不像内存那样提升那么多。
下面列举一些其它的优势:
- 在性能、稳定性、功能方面有很大提升(最直观的体现就是加载网页是占用的内存,模拟器加载百度与开源中国网站时,
WKWebView
占用23M
,而UIWebView
占用85M
); - 更多的支持
HTML5
的特性 - 官方宣称的高达
60fps
的滚动刷新率以及内置手势
Safari
相同的JavaScript
引擎 - 将
UIWebViewDelegate
与UIWebView
拆分成了14类与3个协议(官方文档说明) - 另外用的比较多的,增加加载进度属性:
estimatedProgress
WKWebView的用法
- 加载网页方法与UIWebView相同:
// 网页url
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
// 网络请求
NSURLRequest *request =[NSURLRequest requestWithURL:url];
// 加载网页
[self.webview loadRequest:request];
- 加载文件
// 创建url(可以随便从桌面拉张图片)
NSURL *url = [NSURL fileURLWithPath:@"/Users/ios/Desktop/图片/xxx.jpg"];
// 加载文件
[webView loadFileURL:url allowingReadAccessToURL:url];
- 其余加载方法
-(WKNavigation *)loadRequest:(NSURLRequest *)request
-(WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
-(WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL;
- 网页刷新相关方法
@property (nonatomic, readonly) BOOL canGoBack;
@property (nonatomic, readonly) BOOL canGoForward;
-(WKNavigation *)goBack;
-(WKNavigation *)goForward;
-(WKNavigation *)reload;
-(WKNavigation *)reloadFromOrigin; // 增加的函数
-(WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item; // 增加的函数
-(void)stopLoading;
reloadFromOrigin
会比较网络数据是否有变化,没有变化则使用缓存,否则从新请求。
goToBackForwardListItem
:比向前向后更强大,可以跳转到某个指定历史页面
常用属性
allowsBackForwardNavigationGestures:BOOL类型,是否允许左右划手势导航,默认不允许
estimatedProgress:加载进度,取值范围0~1
title:页面title
scrollView.scrollEnabled:是否允许上下滚动,默认允许
backForwardList:WKBackForwardList类型,访问历史列表,可以通过前进后退按钮访问,或者通过goToBackForwardListItem函数跳到指定页面
相关代理协议
几个常用代理协议:
(1)WKNavigationDelegate
最常用,和UIWebViewDelegate
功能类似,追踪加载过程,有是否允许加载、开始加载、加载完成、加载失败。下面会对方法做简单的说明,并用数字标出调用的先后次序:
// 接收到服务器跳转请求之后调用 (服务器端redirect),不一定调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 3 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 1 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
追踪加载过程方法:
// 2 页面开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 4 开始获取到网页内容时返回
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 5 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
(2)WKUIDelegate
UI界面相关,原生控件支持,三种提示框:输入、确认、警告。首先将web提示框拦截然后再做处理。
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
与JS交互
- (1)WKWebView加载JS
//JS文件路径
NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"];
//读取JS文件内容
NSString *jsContent = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];
//创建用户脚本对象,
//WKUserScriptInjectionTimeAtDocumentStart :HTML文档创建后,完成加载前注入,类似于<head>中
//WKUserScriptInjectionTimeAtDocumentEnd :HTML文件完成加载后注入,类似于<body>中
WKUserScript *script = [[WKUserScript alloc] initWithSource:jsContent injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
//添加用户脚本
[webView.configuration.userContentController addUserScript:script];
- (2)WKWebView执行JS方法
//执行JS方法
[webView evaluateJavaScript:@"test()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
//result为执行js方法的返回值
if(error){
NSLog(@"Success");
}else{
NSLog(@"Fail");
}
}];