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

在显示之前加载ViewController的WebView

  •  1
  • user2875404  · 技术社区  · 7 年前

    我尝试过重写viewDidLoad()、loadView()、一个方便的init()等等,但是在实际显示ViewController之前,我放在那里的东西似乎没有被执行。

     let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
     webViewVC = storyboard.instantiateViewController(withIdentifier: "WebViewController")
    
     if let c = webViewVC.childViewControllers[0] as? WebViewController {
    
         c.dDelegate = self
    
         webViewVC.modalPresentationStyle = .popover
         let popover = webViewVC.popoverPresentationController!
         popover.delegate = self
         popover.permittedArrowDirections = .up
         webViewVC.loadView()
         present(webViewVC, animated: true, completion: nil) //if I don't add this line, the ViewController doesn't seem to get created before showing
     }
    

    那我之前能打什么电话 present() 为了执行ViewController的一些代码?我需要加载以下内容:

    let wwConfiguration = WKWebViewConfiguration()
    
    webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.layer.frame.width, height: self.view.layer.frame.height), configuration: wwConfiguration)
    webView.navigationDelegate = self
    webView.uiDelegate = self
    let url = URL(string: . . .
    
    3 回复  |  直到 7 年前
        1
  •  4
  •   Ashley Mills    7 年前

    你的问题并不完全清楚,但我假设你是从另一个视图控制器,比如说,一个按钮按下来展示你的web视图控制器。像这样的

    enter image description here

    您需要做的是异步处理这个问题。

    • 等它完成
    • 显示web视图控制器

    例子

    WebViewController

    class WebViewController: UIViewController {
    
        @IBOutlet private weak var webView: WKWebView!
    
        var didLoadWebView: (() -> Void)!
    
        func loadWebView(completion: @escaping () -> Void) {
            loadViewIfNeeded()
            didLoadWebView = completion // Save this closure to be called when loaded
            webView.navigationDelegate = self
            webView.load(URLRequest(url: URL(string: "http://apple.com")!))
        }
    }
    
    extension WebViewController: WKNavigationDelegate {
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            didLoadWebView() // Call back to the presenting view controller
        }
    }
    

    呈现 视图控制器

    class ViewController: UIViewController {
    
        @IBAction func showWebView(_ sender: UIButton) {
    
            let wvc = storyboard!.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
            wvc.modalPresentationStyle = .popover
            wvc.popoverPresentationController?.sourceView = sender
            wvc.popoverPresentationController?.sourceRect = sender.bounds
            wvc.loadWebView {
                self.present(wvc, animated: true, completion: nil)
            }
        }
    }
    
        2
  •  0
  •   Athul George    7 年前

    好吧,让我们试着理解行动的要求。他有一个viewController加载一个网页,按照他的说法,加载时间太长,他不想让用户等那么久。同样根据他关于启动时间的问题,我假设视图控制器是他在应用程序启动后显示的第一个视图控制器。

    案例1:webViewVC是启动后的第一个VC

    在这里,我们可以获得的最大“预取”时间是我们在方法ap时获得的时间应用程序:使用选项完成启动:被调用。假设这里没有太多处理器密集的进程执行,那么就没有时间进行预取。因此,唯一的选择是显示一个在UI中应该与launchScreen相似的屏幕,这样用户可能会认为它是仍在加载的应用程序。(就我个人而言,我会做的是将启动屏幕制作成只显示应用程序主题颜色的屏幕,并使用应用程序图标左右将我的第一个屏幕制作成启动屏幕的动画;这样可以提供更好的专业方法,也可以给我足够的时间让事情进展顺利)

    在这里,应用程序将有另一个VC显示给用户,然后再转到webViewVC,这样我们就有了一些预取数据所需的时间。在这种情况下,我将在上一个VC的viewDidLoad加载时开始获取数据。webViewVC显然会在某些操作之后被调用,并且您有时间来完成该操作(可能是由用户完成的)。

    使用虚拟启动屏幕加载VC

        let webViewVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
        let wwConfiguration = WKWebViewConfiguration()
        let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height), configuration: wwConfiguration)
        webView.navigationDelegate = webViewVC
        webView.uiDelegate = webViewVC
        let url = URL(string:"https://www.codemag.com/article/1405051/Understanding-and-Using-iBeacons")
        webView.load(URLRequest(url: url!))
        webViewVC.webView = webView
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
            webViewVC.modalPresentationStyle = .popover
            let popover = webViewVC.popoverPresentationController!
            //popover.delegate = webViewVC
            popover.permittedArrowDirections = .up
            webViewVC.loadView()
            self.present(webViewVC, animated: true, completion: nil)
            webViewVC.showWebView()
        }
    

    此代码实例化webviewVC并开始加载数据,但仅在10秒预取时间后显示。showWebView()方法非常简单

    func showWebView() {
        view.addSubview(webView)
    }
    
    1. 一旦数据获取完成,或者
    2. 您可以在延迟一段时间(在我的示例中是10秒)后加载webView,或者
    3. 您可以通过更改 DispatchQueue.main.asyncAfter() 按钮动作。在这里,您可以使用@AshleyMills代码启用按钮,一旦线索完成。

        3
  •  -2
  •   Ahmad F    7 年前

    尝试使用 webViewVC.loadViewIfNeeded() webViewVC.loadView()