在显示之前加载ViewController的WebView

时间:2018-09-10 12:36:10

标签: ios swift uiviewcontroller wkwebview

我有一个带有包含WebView的ViewController的应用程序。因为WebView所显示的网站很大,所以我想在启动应用程序时加载ViewController,以便用户在使用WebView打开ViewController后立即显示已加载的页面。

我尝试覆盖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 个答案:

答案 0 :(得分:1)

您的问题尚不完全清楚,但是我假设您是通过另一个按钮(例如,按下按钮)从另一个视图控制器中呈现Web视图控制器的。像这样...

enter image description here

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

  • 实例化您的Web视图控制器
  • 开始加载其网络视图
  • 等待完成
  • 呈现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
    }
}

呈现 ViewController

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

答案 1 :(得分:0)

好的,让我们尝试了解OP的要求。他有一个viewController可以加载网页,并且按照他的说法,加载时间太长,并且他不想让用户等待那么长时间。同样根据他关于启动时间的问题,我认为视图控制器是应用启动后他将显示的第一个视图控制器。

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

在这里,我们可以获得的最大“预取”时间是调用方法application:didFinishLaunchingWithOptions:时获得的时间。假设这里没有执行太多的处理器繁重的过程,那么将没有任何时间进行预取。因此,唯一的选择是显示一个在UI中应该与launchScreen类似的屏幕,以便用户可以在应用程序仍在加载时认为它。 (我个人要做的是将启动屏幕设置为仅显示应用程序主题颜色的屏幕,并使用应用程序图标左右将我的第一个屏幕设置为启动屏幕的动画;这提供了更好的专业方法,同时也为我提供了足够的时间让事情滚动)

案例2:webViewVC不是第一个VC

这里,在继续使用webViewVC之前,该应用将向用户显示另一个VC,这样可以给我们一些时间来预取数据。在这种情况下,我将在上一个VC的viewDidLoad时开始获取数据。显然,在执行某些操作之后,将调用webViewVC,这样您就可以花点时间完成该操作(可能由用户执行)。

使用DUMMY启动屏幕加载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. 一旦数据提取完成,您就可以使用@AshleyMills的答案来加载webView或
  2. 您可以在一段时间(在我的示例中为10秒)延迟后加载webView或
  3. 您可以通过将DispatchQueue.main.asyncAfter()内的所有代码更改为按钮动作来将页面加载为动作(例如,单击按钮时)。线索完成后,您可以在此处使用@AshleyMills代码启用按钮。

干杯!

答案 2 :(得分:-2)

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