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 { }