Как предварительно загрузить WKWebView перед загрузкой его viewcontroller? - PullRequest
0 голосов
/ 02 января 2019

Я задаю этот вопрос, потому что после некоторых исследований я не нашел удовлетворительных ответов в Интернете.

Мне нужно просто, у меня есть 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 ]

0 голосов
/ 11 января 2019

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

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

}

И 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()


    }    
}

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

0 голосов
/ 02 января 2019

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.Но webviewToLoad - это , а не - это то же самое webView, которое появляется в ViewController после перехода:

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

То, что - это веб-представление, которое вы хотите предоставитьсодержание к.Вы вообще этого не делаете;Ни один из вашего кода не затрагивает webView, чтобы придать ему содержание.

Я думаю, что суть вашего заблуждения здесь:

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

Вы не можете просто заменить один веб-просмотр другим и ожидать чего-томагически работать;loadView все равно заставит исходное пустое веб-представление быть вашим видом и появиться в интерфейсе.

Вместо этого вам нужна эта архитектура:

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...