为什么WKWebView没有打开target =“_ blank”的链接?

时间:2014-09-07 17:44:29

标签: ios wkwebview

WKWebView不会打开任何包含target="_blank" a.k.a的链接。'在新窗口中打开'属性在其HTML <a href> - 标记中。

15 个答案:

答案 0 :(得分:138)

我的解决方案是取消导航并再次使用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;
}

答案 1 :(得分:54)

@Cloud Xu的回答是正确答案。仅供参考,这里是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
}

答案 2 :(得分:35)

使用最新版本的Swift 4.2 +

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
}

答案 3 :(得分:21)

将自己添加为 WKNavigationDelegate

_webView.navigationDelegate = self;

并在委托回调中实现以下代码 decisionPolicyForNavigationAction: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);
}

P.S。:这段代码来自我的小项目STKWebKitViewController,它围绕WKWebView包装了一个可用的UI。

答案 4 :(得分:12)

如果您已经设置了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方法了。

答案 5 :(得分:8)

这些解决方案都不适合我,我确实解决了这个问题:

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

答案 6 :(得分:7)

我确认Bill Weinman的Swift代码是正确的。但是需要提一下,你还需要委托UIDelegate才能使用它,以防你不熟悉像我这样的iOS开发人员。

这样的事情:

self.webView?.UIDelegate = self

因此,您需要进行三项更改。

答案 7 :(得分:3)

您还可以推送另一个视图控制器,或打开新标签等:

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
}

答案 8 :(得分:2)

Cloud xu的答案解决了我的问题。

如果有人需要等效的Swift(4.x / 5.0)版本,则为:

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    if let frame = navigationAction.targetFrame,
        frame.isMainFrame {
        return nil
    }
    // for _blank target or non-mainFrame target
    webView.load(navigationAction.request)
    return nil
}

当然,您首先需要设置webView.uiDelegate

答案 9 :(得分:1)

我遇到了一些仅使用x = str (input("Enter Binario: ")) c = len (x) decimal = 0 b ="" for y in (b): if ( b == "1"): b = 1 else : if (b =="0"): b =0 z = c - 1 t = (2**z) * x decimal = decimal + t print (decimal) 无法解决的问题。所以我使用创建一个新的webView来做它只是工作正常。

webView.load(navigationAction.request)

答案 10 :(得分:1)

解决方案

allen huang answer

详细

xCode 9.2,Swift 4

推送目标的完整样本=“_空白”链接

import UIKit
import WebKit

class ViewController: UIViewController {

    var urlString = "http://google.com"
    var webView: WKWebView!
    fileprivate var webViewIsInited = false
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillLayoutSubviews() {
        if !webViewIsInited {
            webViewIsInited = true
            if webView == nil {
                webView = WKWebView(frame: UIScreen.main.bounds, configuration: WKWebViewConfiguration())
            }

            view.addSubview(webView)
            webView.navigationDelegate = self
            webView.uiDelegate = self
            webView.loadUrl(string: urlString)
        }
    }
}

extension ViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        decisionHandler(.allow)
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if let host = webView.url?.host {
            self.navigationItem.title = host
        }
    }
}

extension ViewController: WKUIDelegate {

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            let vc = ViewController()
            vc.urlString = navigationAction.request.url?.absoluteString ?? "http://google.com"
            vc.view.frame = UIScreen.main.bounds
            vc.webView = WKWebView(frame: UIScreen.main.bounds, configuration: configuration)
            navigationController?.pushViewController(vc, animated: false)
            return vc.webView
        }
        return nil
    }
}

extension WKWebView {

    func loadUrl(string: String) {
        if let url = URL(string: string) {
            if self.url?.host == url.host {
                self.reload()
            } else {
                load(URLRequest(url: url))
            }
        }
    }
}

enter image description here

答案 11 :(得分:1)

这对我有用:

data: any;
  answer:any[] = [];
  constructor(public navCtrl: NavController) {
    this.data = {"questionnaire": {
        "id": "5ac5f074867d190bc471dc59",
        "name": "Diabetes Questionnaire Test",
      "item": [
        {
          "prefix": "1",
          "text": "Do you have family history of diabetes?",
          "Questiontype": "choice",
          "options": [
            {
              "value": "Yes",
              "checked": false
            },
            {
              "value": "No",
              "checked": false
            },
            {
              "value": "I Don't know",
              "checked": false
            }
          ]
        },
        {
          "prefix": "2",
          "text": "Are you hypertensive?",
          "Questiontype": "choice",
          "options": [
            {
              "value": "Yes",
              "checked": false
            },
            {
              "value": "No",
              "checked": false
            },
            {
              "value": "I Don't Know",
              "checked": false
            }
          ]
        }
      ]
    }
    };
  }

  updateAnswer(index,ansindex,value,checked){
    if(!Array.isArray(this.answer[index])){
      this.answer[index] = []
    }
    if(checked){
     this.answer[index][ansindex] =  value
    }else{
      this.answer[index].splice(ansindex,1)
    }
  }

正如您所看到的,我们在这里所做的只是使用新网址打开一个新的-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { WKWebView *newWebview = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration]; newWebview.UIDelegate = self; newWebview.navigationDelegate = self; [newWebview loadRequest:navigationAction.request]; self.view = newWebview; return newWebview; } return nil; } - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { decisionHandler(WKNavigationActionPolicyAllow); } - (void)webViewDidClose:(WKWebView *)webView { self.view = self.webView; } 并控制关闭的可能性,就好像您需要显示webView的响应一样在第一个。

答案 12 :(得分:0)

**Use following function to create web view**

func initWebView(configuration: WKWebViewConfiguration) 
{
        let webView = WKWebView(frame: UIScreen.main.bounds, configuration: configuration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        view.addSubview(webView)
        self.webView = webView
    }

**In View Did Load:**

 if webView == nil { initWebView(configuration: WKWebViewConfiguration()) }
   webView?.load(url: url1)


**WKUIDelegate Method need to be implemented**

extension WebViewController: WKUIDelegate {

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        // push new screen to the navigation controller when need to open url in another "tab"
        print("url:\(String(describing: navigationAction.request.url?.absoluteString))")
        if let url = navigationAction.request.url, navigationAction.targetFrame == nil {
            let viewController = WebViewController()
            viewController.initWebView(configuration: configuration)
            viewController.url1 = url
            DispatchQueue.main.async { [weak self] in
                self?.navigationController?.pushViewController(viewController, animated: true)
            }
            return viewController.webView
        }

        return nil
    }
}

extension WKWebView 

{
    func load(url: URL) { load(URLRequest(url: url)) }
}

答案 13 :(得分:0)

要在Mobile Safari中打开_blank页面,如果您使用的是Swift,则:

webView.navigationDelegate = self

并在WKNavigationDelegate中实现此目标:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if navigationAction.targetFrame == nil, let url = navigationAction.request.url {
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
    }
    decisionHandler(WKNavigationActionPolicy.allow)
}

答案 14 :(得分:0)

使用此方法在网页视图中下载 pdf

func webView(_ webView: WKWebView, createWebViewWith 配置: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?