为什么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 }