1.创建wkwebview,除了正常的UI和delegate设置,关键一点是配置WKWebViewConfiguration,需要js回调的要设置允许js回调。
2.WKNavigationDelegate主要方法
- (void)webView:(WKWebView* )webView decidePolicyForNavigationAction:(WKNavigationAction* )navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
/*
//当网页即将发起新的请求时调用此代理,可以对跳转的方式做处理,如拦截url,使用新的页面打开,或根据特定url判断跳转其他地址等。对html的a标签处理也放在这里
//需要注意的是:
//当取消加载的时候要执行回调
decisionHandler(WKNavigationActionPolicyCancel);
//继续加载执行回调
decisionHandler(WKNavigationActionPolicyAllow);
*/
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
//此代理方法为当webview请求完成时调用
//response中包含状态码,可以知道请求是否成功
//block回调同样有允许和取消,根据需求自行调用
decisionHandler (WKNavigationResponsePolicyAllow);
decisionHandler (WKNavigationResponsePolicyCancel)
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
//此代理方法是当webview加载完成之后调用,在这里可以处理一些js逻辑
//js语句既可以是调用js方法,也可以是为页面添加js方法
//禁用选中效果
[webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
[webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];
//为当前页所有a标签添加标识符"newtab:"
NSString *newVCStr = @"var allLinks = document.getElementsByTagName('a'); if (allLinks) {var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target'); if (target && target == '_blank') {link.setAttribute('target','_self');link.href = 'newtab:'+link.href;}}}";
[webView evaluateJavaScript:newVCStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
//为页面添加close方法,并与html页面的close方法绑定,要监听close方法还需要注册js监听
NSString *closeStr = @"var close = function() {window.webkit.messageHandlers.close.postMessage(null)}"; [webView evaluateJavaScript:closeStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
}
注册js回调监听
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"close"];
注意,此方法同kvo类似,注册之后还需要在合适的时机移除,否则内存泄漏,并且不要重复添加
3.手势禁用
方法1:通过js方法,让页面调用js代码时被禁用,或者html接收到手势时不处理,如同上面的禁用选中效果。
方法2:利用runtime机制替换wkwebview手势action
wkwebview中封装了很多手势action在wkwebview.scrollView.subviews中的WKContentView上。
可以通过WKContentView.gestureRecognizers查看到所有action,此时运用runtime,替换响应的方法,即可变更或者禁用响应手势
例如:将双击手势的方法替换为什么也不执行
- (void)changeWebViewDoubleTapRecognized { for (UIView *view in _webView.scrollView.subviews) {
if ([view isKindOfClass:NSClassFromString(@"WKContentView")]){
SEL thisSelector = @selector(emptyMethod);
Method thisMethod = class_getInstanceMethod([self class], thisSelector);
NSString *oldMethod = @"_doubleTapRecognized:";
SEL mainPopSelector = NSSelectorFromString(oldMethod);
Method doubleTapMethod = class_getInstanceMethod([view class], mainPopSelector);
method_exchangeImplementations(thisMethod, doubleTapMethod); } }
}
- (void)emptyMethod { }