Загрузите WebView ViewController перед отображением - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть приложение с ViewController, которое содержит WebView. Поскольку веб-сайт, на котором отображается WebView, довольно большой, я хотел бы загрузить ViewController во время запуска приложения, чтобы, как только пользователь открыл ViewController с WebView, он отобразит уже загруженную страницу.

Я попытался переопределить 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 голосов
/ 10 сентября 2018

Это не совсем понятно из вашего вопроса, но я предполагаю, что вы представляете свой контроллер веб-представления из другого контроллера представления, скажем, нажатием кнопки.Примерно так ...

enter image description here

Что вам нужно сделать, это обработать это асинхронно.

  • Создание экземпляра контроллера веб-представления
  • Начало загрузки веб-представления
  • Подождите, пока это не завершится
  • Представьте контроллер веб-представления

Пример…

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)
        }
    }
}
0 голосов
/ 10 сентября 2018

Хорошо, давайте попробуем понять, о чем просит ОП. У него есть viewController, который загружает веб-страницу, и, по его мнению, его загрузка занимает слишком много времени, и он не хочет заставлять пользователя ждать так долго. Также, согласно его вопросу о времени запуска, я предполагаю, что контроллер представления является первым контроллером представления, который он будет отображать после запуска приложения.

Случай 1: WebViewVC является первым VC после запуска

Здесь максимальное время «предварительной выборки», которое мы можем получить, это время, которое мы получаем, когда вызывается приложение метода: didFinishLaunchingWithOptions:. Предполагая, что здесь выполняется не так много процессорного процесса, времени на предварительную выборку не будет. Таким образом, единственный вариант - показать экран, который в пользовательском интерфейсе должен быть похож на launchScreen, чтобы пользователь мог считать его приложением, которое все еще загружается. (Лично я бы сделал экран запуска в виде экрана, который просто отображает цвет темы приложения и анимировал мой первый экран в качестве экрана запуска с помощью значка приложения или около того; это дает лучший профессиональный подход и достаточно времени для меня, чтобы катиться)

Случай 2: WebViewVC - не первый VC

Здесь, приложение будет отображать пользователю другой VC, прежде чем перейти к webViewVC, так что у нас будет время, необходимое для предварительной выборки данных. В этом случае я бы начал извлекать данные, пока viewDidLoad предыдущего VC. Очевидно, что webViewVC будет вызываться после некоторых действий, и у вас будет время до того, как это действие будет выполнено (вероятно, пользователем).

Загрузка ВК с помощью экрана запуска DUMMY

    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 для загрузки веб-просмотра после завершения выборки данных или
  2. Вы можете загрузить webView с некоторой задержкой (в моем примере это 10 секунд) или
  3. Вы можете загрузить страницу как действие (например, при нажатии кнопки), изменив весь код внутри DispatchQueue.main.asyncAfter() на действие кнопки. Здесь вы можете использовать код @AshleyMills для включения кнопки после завершения отведения.

Ура!

0 голосов
/ 10 сентября 2018

Попробуйте использовать webViewVC.loadViewIfNeeded() вместо webViewVC.loadView()

...