代码之家  ›  专栏  ›  技术社区  ›  cmii

如何在推送wkwebview的viewcontroller之前预加载wkwebview?

  •  1
  • cmii  · 技术社区  · 5 年前

    我问这个问题是因为经过一些研究,我在网上没有找到令人满意的答案。

    我的需要很简单,我有一个uiTableViewController,当我单击一个单元格时,我需要显示一个加载程序(在加载wkWebViewContent时),然后推下一个uiViewController,其中wkWebView已经加载。

    我试过这个:

    class TableViewController: UITableViewController, WKNavigationDelegate {
    
       var webviewToLoad:WKWebView!
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
            let htmlString = "some html content"
    
    
            webviewToLoad = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
            webviewToLoad.navigationDelegate = self
            webviewToLoad.loadHTMLString(htmlString, baseURL: Bundle.main.resourceURL)
        }
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
            if segue.identifier == "postview"{
                let destinationController = segue.destination as! ViewController
                destinationController.webView= webviewToLoad
            }
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            print("Loaded!")
            self.performSegue(withIdentifier: "postview", sender: self)
        }
    
    }
    
    class ViewController: UIViewController, WKUIDelegate {
    
        var webView: WKWebView!
    
        override func loadView() {
    
            let webConfiguration = WKWebViewConfiguration()
            webView = WKWebView(frame: .zero, configuration: webConfiguration)
            webView.uiDelegate = self
            self.view = webView
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }
    

    didFinish 调用,但最终的WkWebView为空。

    也许这不是正确的方法,有什么想法吗?

    2 回复  |  直到 5 年前
        1
  •  1
  •   matt    5 年前

    调用了DidFinish,但最终的WkWebView为空

    因为你从未做过任何事 空白。你的代码说:

    var webviewToLoad:WKWebView!
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        webviewToLoad = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
        webviewToLoad.navigationDelegate = self
        webviewToLoad.loadHTMLString(htmlString, baseURL: Bundle.main.resourceURL)
    }
    

    所以你所做的一切都是关于 webviewToLoad . 但是 网络浏览 相同的 webView 出现在Segue之后的视图控制器中:

    class ViewController: UIViewController, WKUIDelegate {
        var webView: WKWebView!
    }
    

    是要为其提供内容的Web视图。您根本没有这样做;您的代码都不涉及 WebVIEW 给它内容。

    我认为你困惑的核心是:

    if segue.identifier == "postview"{
        let destinationController = segue.destination as! ViewController
        destinationController.webView = webviewToLoad
    }
    

    你不能简单地用一个Web视图代替另一个,并且期望事情神奇地工作; loadView 仍将导致原始空白Web视图成为您的视图并显示在界面中。

    相反,您想要的是这个体系结构:

    if segue.identifier == "postview"{
        let destinationController = segue.destination as! ViewController
        // make `loadView` run
        destinationController.loadViewIfNeeded() 
        let webView = destinationController.webView
        // now load _this_ `webView` with content!
        let htmlString = "some html content"
        webView.loadHTMLString(htmlString, baseURL: Bundle.main.resourceURL)
    }
    
        2
  •  0
  •   cmii    5 年前

    因为@matt的回答不完整,所以在推下一个视图控制器之前,我的解决方案是等待WebView加载:

    class TableViewController: UITableViewController, WKNavigationDelegate, WKUIDelegate {
    
        var webviewToLoad:WKWebView!
        var destinationController:ViewController!
        var alert:UIAlertController!
    
        override func viewDidLoad() {
            super.viewDidLoad()       
        }
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
            alert = UIAlertController(title: "Alert", message: "Loading", preferredStyle: .alert)
    
            destinationController = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ViewController") as? ViewController
    
            destinationController!.loadViewIfNeeded()
            let webView:WKWebView = destinationController!.webView
            webView.navigationDelegate = self
            webView.uiDelegate = self
    
            self.present(alert, animated: true, completion: nil)
    
            let htmlString = "my html code"
            webView.loadHTMLString(htmlString, baseURL: Bundle.main.resourceURL)
        }
    
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    
            alert.dismiss(animated: false, completion: nil)
            self.navigationController?.pushViewController(destinationController!, animated: true)
        }
    
    }
    

    以及内置WebView的uiviewController:

    class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
    
        var webView: WKWebView!
        @IBOutlet var viewForWebview: UIView!
        @IBOutlet var heightWebviewConstraint: NSLayoutConstraint!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
        }
    
         override func loadView() {
    
            super.loadView()
    
            webView = WKWebView()
    
            if (webView != nil) {
                webView!.frame = viewForWebview.frame
    
                webView.translatesAutoresizingMaskIntoConstraints = false
    
                viewForWebview.addSubview(webView!)
    
                NSLayoutConstraint.activate([
                   webView.topAnchor.constraint(equalTo: viewForWebview.topAnchor),
                    webView.bottomAnchor.constraint(equalTo: viewForWebview.bottomAnchor),
                    webView.leadingAnchor.constraint(equalTo: viewForWebview.leadingAnchor),
                    webView.trailingAnchor.constraint(equalTo: viewForWebview.trailingAnchor)
                    ])
            }
    
        }
    
    
        override func viewDidLayoutSubviews() {
    
            super.viewDidLayoutSubviews()
    
            heightWebviewConstraint.constant = self.webView.scrollView.contentSize.height
            self.view.setNeedsLayout()
            self.view.setNeedsUpdateConstraints()
    
    
        }    
    }
    

    此代码在WebView加载期间显示一个uiAlertController,然后关闭警报控制器,并推送下一个已加载WebView的控制器。