WKWebVIew是UIWebView的代替品,新的WebKit框架把原来的功能拆分成许多小类。本例中主要用到了WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler三个委托和配置类WKWebViewConfiguration去实现webView的request控制,界面控制,js交互,alert重写等功能。 使用WKWebView需要引入#import <WebKit/WebKit.h>
加载页面,配置委托和手势等
//加载页面
config = [[WKWebViewConfiguration alloc] init];
config.preferences.minimumFontSize = 18;
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
preferences.minimumFontSize = 30.0;
self.config.preferences = preferences;
//设置位置和委托
webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
webView.navigationDelegate = self
webView.UIDelegate = self
[self.view addSubview:webView];
//加载网页
[webView loadRequest:[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"www.baidu.com"]]];
//加载本地页面
[webView loadRequest:[[NSURLRequest alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]]]];
//允许手势,后退前进等操作
[webView setAllowsBackForwardNavigationGestures:Yes];
前进,后退,刷新,进度条
//前进
[webView goBack];
//后退
[webView goForward];
//刷新
[webView reload];
//监听是否可以前进后退,修改btn.enable属性
[webView addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil];
//监听加载进度
[webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
//重写self的kvo方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"loading"]) {
gobackBtn.enabled = webView.canGoBack;
forwardBtn.enabled = webView.canGoForward;
}
if (]keyPath isEqualToString:@"estimatedProgress"]) {
//progress是UIProgressView
progress.hidden = webView.estimatedProgress == 1
[progress setProgress:webView.estimatedProgress animated:YES];
}
}
js中alert的拦截
在WKWebview中,js的alert是不会出现任何内容的,你必须重写WKUIDelegate委托的runJavaScriptAlertPanelWithMessage message方法,自己处理alert。类似的还有Confirm和prompt也和alert类似,这里我只以alert为例。
//alert捕获
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"ios-alert" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
app调js方法
WKWebView调用js方法和UIWebView类似,一个是evaluateJavaScript,一个是stringByEvaluatingJavaScriptFromString。获取返回值的方式不同,WKWebView用的是回叫函数获取返回值
//直接调用js
[webView evaluateJavaScript:@"hi()", completionHandler: nil];
//调用js带参数
[webView evaluateJavaScript:@"hello('liuyanwei')", completionHandler: nil];
//调用js获取返回值
[webView evaluateJavaScript:@"getName()" completionHandler:^(id _Nullable obj, NSError * _Nullable error)
NSLog(@"evaluateJavaScript, obj = %@, error = %@", obj, error);
}];
js调app方法
UIwebView没有js调app的方法,而在WKWebView中有了改进。具体步骤分为app注册handler,app处理handler委托,js调用三个步骤
1:注册handler需要在webView初始化之前,如示例,注册了一个webViewApp的handler
config = [WKWebViewConfiguration new];
//注册js方法
[config.userContentController addScriptMessageHandler:self name: @"webViewApp"];
webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
2:处理handler委托。ViewController实现WKScriptMessageHandler委托的func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)方法
//实现WKScriptMessageHandler委托
@interface WKWebviewViewController () <WKNavigationDelegate, WKUIDelegate,WKScriptMessageHandler>
//实现js调用ios的handle委托
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",message.body);
if ([message.name isEqualToString:@"getParams"]) {
NSLog(@"");
}
}
3:js调用
通过 window.webkit.messageHandlers.webViewApp找到之前注册的handler对象,然后调用postMessage方法把数据传到app,app通过上一步的方法解析方法名和参数
var message = {
'method' : 'hello',
'param1' : 'liuyanwei',
};
window.webkit.messageHandlers.webViewApp.postMessage(message);
如果需要app对js的调用有所响应,可以通过回叫函数的方式回应js。可以在调用app的时候增加一个js回叫函数名 app在处理完之后可以呼叫回叫函数并把需要的参数通过回叫函数的方式进行传递
webView生命周期和跳转代理
该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
以上内容均为转载:
出处:http://www.360doc.com/content/17/0519/11/35563379_655242400.shtml