为什么WKWebView不打开target =“_ blank”的链接

WKWebView不打开任何具有target =“_ blank”的链接。 在他们的HTML-Tag中的“在新窗口中打开”属性。

我的解决scheme是取消导航,并再次加载与请求loadRequest: 这将会像在当前帧中总是打开新窗口的UIWebView那样来类似的行为。

首先你需要有一个WKUIDelegate的实现。 并将其设置为_webview.UIDelegate 。 然后执行:

 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [webView loadRequest:navigationAction.request]; } return nil; } 

@云徐的回答是正确的答案。 仅供参考,这里是在Swift中:

 // this handles target=_blank links by opening them in the same view func webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! { if navigationAction.targetFrame == nil { webView.loadRequest(navigationAction.request) } return nil } 

将自己添加为WKNavigationDelegate

 _webView.navigationDelegate = self; 

并在委托callback中实现以下代码:resolvePolicyForNavigationAction:decisionHandler:

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { //this is a 'new window action' (aka target="_blank") > open this URL externally. If we´re doing nothing here, WKWebView will also just do nothing. Maybe this will change in a later stage of the iOS 8 Beta if (!navigationAction.targetFrame) { NSURL *url = navigationAction.request.URL; UIApplication *app = [UIApplication sharedApplication]; if ([app canOpenURL:url]) { [app openURL:url]; } } decisionHandler(WKNavigationActionPolicyAllow); } 

PS:这个代码来自我的小项目STKWebKitViewController ,它围绕WKWebView封装了一个可用的UI。

使用最新版本的Swift 3+

 import WebKit 

WKUIDelegate扩展你的课程

为webview设置代理

 self.webView.uiDelegate = self 

实施协议方法

 func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil } 

我确认Bill Weinman的Swift代码是正确的。 但是需要提到的是,如果你是像我一样开发iOS的新手,你还需要委托UIDelegate来工作。

像这样的东西:

 self.webView?.UIDelegate = self 

所以有三个地方需要进行更改。

如果你已经设置了WKWebView.navigationDelegate

WKWebView.navigationDelegate = self;

你只需要实现:

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { BOOL shouldLoad = [self shouldStartLoadWithRequest:navigationAction.request]; // check the url if necessary if (shouldLoad && navigationAction.targetFrame == nil) { // WKWebView ignores links that open in new window [webView loadRequest:navigationAction.request]; } // always pass a policy to the decisionHandler decisionHandler(shouldLoad ? WKNavigationActionPolicyAllow : WKNavigationActionPolicyCancel); } 

这样你就不需要实现WKUIDelegate方法。

这些解决scheme都没有为我工作,我通过以下方式解决了这个问题:

1)实现WKUIDelegate

 @interface ViewController () <WKNavigationDelegate, WKUIDelegate> 

2)设置wkWebview的UIDelegate委托

 self.wkWebview.UIDelegate = self; 

3)实现createWebViewWithConfiguration方法

 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; [[UIApplication sharedApplication] openURL:[navigationAction.request URL]]; } return nil; } 

你也可以推另一个视图控制器,或打开一个新的选项卡等:

 func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { var wv: WKWebView? if navigationAction.targetFrame == nil { if let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController { vc.url = navigationAction.request.URL vc.webConfig = configuration wv = vc.view as? WKWebView self.navigationController?.pushViewController(vc, animated: true) } } return wv } 

我遇到了一些无法通过使用webView.load(navigationAction.request)解决的问题。 所以我使用创build一个新的webView来做,它只是正常工作。

 //MARK:- WKUIDelegate func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { NSLog(#function) if navigationAction.targetFrame == nil { NSLog("=> Create a new webView") let webView = WKWebView(frame: self.view.bounds, configuration: configuration) webView.uiDelegate = self webView.navigationDelegate = self self.webView = webView return webView } return nil }