1.創(chuàng)建wkwebview熊痴,除了正常的UI和delegate設(shè)置缔赠,關(guān)鍵一點(diǎn)是配置WKWebViewConfiguration但金,需要js回調(diào)的要設(shè)置允許js回調(diào)涨醋。
2.WKNavigationDelegate主要方法
- (void)webView:(WKWebView* )webView decidePolicyForNavigationAction:(WKNavigationAction* )navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
/*
//當(dāng)網(wǎng)頁即將發(fā)起新的請(qǐng)求時(shí)調(diào)用此代理瓜饥,可以對(duì)跳轉(zhuǎn)的方式做處理,如攔截url浴骂,使用新的頁面打開乓土,或根據(jù)特定url判斷跳轉(zhuǎn)其他地址等。對(duì)html的a標(biāo)簽處理也放在這里
//需要注意的是:
//當(dāng)取消加載的時(shí)候要執(zhí)行回調(diào)
decisionHandler(WKNavigationActionPolicyCancel);
//繼續(xù)加載執(zhí)行回調(diào)
decisionHandler(WKNavigationActionPolicyAllow);
*/
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
//此代理方法為當(dāng)webview請(qǐng)求完成時(shí)調(diào)用
//response中包含狀態(tài)碼溯警,可以知道請(qǐng)求是否成功
//block回調(diào)同樣有允許和取消帐我,根據(jù)需求自行調(diào)用
decisionHandler (WKNavigationResponsePolicyAllow);
decisionHandler (WKNavigationResponsePolicyCancel)
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
//此代理方法是當(dāng)webview加載完成之后調(diào)用,在這里可以處理一些js邏輯
//js語句既可以是調(diào)用js方法愧膀,也可以是為頁面添加js方法
//禁用選中效果
[webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
[webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];
//為當(dāng)前頁所有a標(biāo)簽添加標(biāo)識(shí)符"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方法綁定,要監(jiān)聽close方法還需要注冊(cè)js監(jiān)聽
NSString *closeStr = @"var close = function() {window.webkit.messageHandlers.close.postMessage(null)}"; [webView evaluateJavaScript:closeStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
}
注冊(cè)js回調(diào)監(jiān)聽
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"close"];
注意檩淋,此方法同kvo類似芬为,注冊(cè)之后還需要在合適的時(shí)機(jī)移除,否則內(nèi)存泄漏蟀悦,并且不要重復(fù)添加
3.手勢(shì)禁用
方法1:通過js方法媚朦,讓頁面調(diào)用js代碼時(shí)被禁用,或者h(yuǎn)tml接收到手勢(shì)時(shí)不處理日戈,如同上面的禁用選中效果询张。
方法2:利用runtime機(jī)制替換wkwebview手勢(shì)action
wkwebview中封裝了很多手勢(shì)action在wkwebview.scrollView.subviews中的WKContentView上。
可以通過WKContentView.gestureRecognizers查看到所有action浙炼,此時(shí)運(yùn)用runtime份氧,替換響應(yīng)的方法唯袄,即可變更或者禁用響應(yīng)手勢(shì)
例如:將雙擊手勢(shì)的方法替換為什么也不執(zhí)行
- (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 { }