WKWebView在iOS11,Swift 4中如何打开一个新标签页?

9

我知道这个问题已经被问了很多次,我认为我已经查看了所有关于此的帖子,但我仍然无法让它工作。我是Swift的新手,我认为这阻碍了我能够从其他答案中适应代码片段。

所以这是我的问题:

我正在使用WKWebView在我的应用程序中查看网站。当我点击打开一个新标签页的链接时,什么也不会发生。我希望新标签页在Safari中打开或者至少在新的WKWebView中打开。我尝试实现https://dev59.com/Xl8e5IYBdhLWcg3wd6Q6#27391215Open a WKWebview target="_blank" link in Safari等许多类似答案中的解决方案,但没有取得任何进展。我需要做什么才能使它在Swift 4中工作?

由于我无法成功实现任何其他解决方案,因此目前只有以下代码:

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

但是它似乎没有起到任何作用。如果有人能帮助我指明方向,我将非常感激。
2个回答

11

我已经复制了一个 WKWebView 项目(从文件夹加载本地 html)的示例代码,需要具有 target=_blank 的链接在新浏览器窗口中打开。

我强调了必须具备以下3个条件才能正确打开链接。

  1. class ViewController extends WKUIDelegate
  2. self.webView.uiDelegate = self
  3. 使用 UIApplication.shared.open 替代 webView.load

请让我知道它是否有效,如果有人能提出改进样本代码的建议,那也会对我有所帮助 :)

下面是适用于 Xcode 9.2, Swift 4 的完整示例代码。

祝你好运

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    @IBOutlet weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.uiDelegate = self

        let htmlPath = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "www")
        let htmlUrl = URL(fileURLWithPath: htmlPath!)
        let htmlDir = Bundle.main.url(forResource: "www", withExtension: nil)
        webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlDir!)
    }

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            //webView.load(navigationAction.request)
            UIApplication.shared.open(navigationAction.request.url!, options: [:])
        }
        return nil
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override var prefersStatusBarHidden: Bool {
        return true
    }

}

谢谢!我的Webview没有处理URL事件,我不知道该使用哪个委托方法来处理它。 - htafoya

1

详情

  • Xcode 10.2 (10E125),Swift 5

解决方案

extension ViewController: 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"
        if let url = navigationAction.request.url, navigationAction.targetFrame == nil {
            let viewController = ViewController()
            DispatchQueue.main.async { [weak self] in
                self?.navigationController?.pushViewController(viewController, animated: true)
            }
            // .....
            return viewController.webView
        }
        return nil
    }

完整样例

Info.plist

在您的Info.plist文件中添加传输安全设置。
 <key>NSAppTransportSecurity</key>
 <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
 </dict>

代码

import UIKit
import WebKit

class ViewController: UIViewController {

    private lazy var url = URL(string: "https://google.com")!
    private weak var webView: WKWebView?

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if webView == nil { initWebView(configuration: WKWebViewConfiguration()) }
        webView?.load(url: url)
    }
}

extension ViewController: 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"
        if let url = navigationAction.request.url, navigationAction.targetFrame == nil {
            let viewController = ViewController()
            viewController.initWebView(configuration: configuration)
            viewController.url = 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)) }
}

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接