How to preload WKWebView before pushing its viewcontroller?












1















I ask this question because after some research, I haven't found satisfactory answers on the Web.



My need is simple, I have a UITableViewController, when I click on a cell, I need to display a loader (while loading the WKWebViewContent), THEN push the next UIViewController, with the WKWebView already loaded inside.



I tried this :



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 is called, but the final WKWebView is blank.



Maybe it isn't the right way, any ideas?










share|improve this question

























  • Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

    – Spads
    Jan 2 at 17:23











  • if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

    – Galo Torres Sevilla
    Jan 2 at 17:44











  • You make no attempt to set the frame of the web view.

    – rmaddy
    Jan 2 at 18:12
















1















I ask this question because after some research, I haven't found satisfactory answers on the Web.



My need is simple, I have a UITableViewController, when I click on a cell, I need to display a loader (while loading the WKWebViewContent), THEN push the next UIViewController, with the WKWebView already loaded inside.



I tried this :



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 is called, but the final WKWebView is blank.



Maybe it isn't the right way, any ideas?










share|improve this question

























  • Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

    – Spads
    Jan 2 at 17:23











  • if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

    – Galo Torres Sevilla
    Jan 2 at 17:44











  • You make no attempt to set the frame of the web view.

    – rmaddy
    Jan 2 at 18:12














1












1








1








I ask this question because after some research, I haven't found satisfactory answers on the Web.



My need is simple, I have a UITableViewController, when I click on a cell, I need to display a loader (while loading the WKWebViewContent), THEN push the next UIViewController, with the WKWebView already loaded inside.



I tried this :



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 is called, but the final WKWebView is blank.



Maybe it isn't the right way, any ideas?










share|improve this question
















I ask this question because after some research, I haven't found satisfactory answers on the Web.



My need is simple, I have a UITableViewController, when I click on a cell, I need to display a loader (while loading the WKWebViewContent), THEN push the next UIViewController, with the WKWebView already loaded inside.



I tried this :



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 is called, but the final WKWebView is blank.



Maybe it isn't the right way, any ideas?







ios swift loading wkwebview preload






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 18:11









rmaddy

245k27326389




245k27326389










asked Jan 2 at 16:32









cmiicmii

1,76462547




1,76462547













  • Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

    – Spads
    Jan 2 at 17:23











  • if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

    – Galo Torres Sevilla
    Jan 2 at 17:44











  • You make no attempt to set the frame of the web view.

    – rmaddy
    Jan 2 at 18:12



















  • Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

    – Spads
    Jan 2 at 17:23











  • if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

    – Galo Torres Sevilla
    Jan 2 at 17:44











  • You make no attempt to set the frame of the web view.

    – rmaddy
    Jan 2 at 18:12

















Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

– Spads
Jan 2 at 17:23





Perhaps your ViewController.loadView() is overridding the webView set in TableViewController.prepare()

– Spads
Jan 2 at 17:23













if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

– Galo Torres Sevilla
Jan 2 at 17:44





if it's an http request, did you set the transportSecurity and arbitraryLoads in the .plist of your project?

– Galo Torres Sevilla
Jan 2 at 17:44













You make no attempt to set the frame of the web view.

– rmaddy
Jan 2 at 18:12





You make no attempt to set the frame of the web view.

– rmaddy
Jan 2 at 18:12












2 Answers
2






active

oldest

votes


















1















didFinish is called, but the final WKWebView is blank




Because you never did anything to make it not blank. Your code says:



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


So everything you do is about webviewToLoad. But webviewToLoad is not the same webView that appears in the ViewController after the segue:



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


That is the web view you want to give content to. You are not doing that at all; none of your code touches webView to give it content.



I think the heart of your confusion is here:



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


You cannot just substitute one web view for another and expect things to magically work; loadView will still cause the original blank web view to be your view and to appear in the interface.



Instead, what you want is this architecture:



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





share|improve this answer


























  • Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

    – matt
    Jan 2 at 19:19











  • Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

    – cmii
    Jan 8 at 9:56



















0














As @matt's answer was incomplete, here my solution to wait the webview loading before pushing the next view controller:



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

}


And the UIViewController with the webview inside:



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


}
}


This code displays an UIAlertController during the webview loading, then dismiss the alert controller, and pushing the next controller, with the webview already loaded.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54009892%2fhow-to-preload-wkwebview-before-pushing-its-viewcontroller%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1















    didFinish is called, but the final WKWebView is blank




    Because you never did anything to make it not blank. Your code says:



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


    So everything you do is about webviewToLoad. But webviewToLoad is not the same webView that appears in the ViewController after the segue:



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


    That is the web view you want to give content to. You are not doing that at all; none of your code touches webView to give it content.



    I think the heart of your confusion is here:



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


    You cannot just substitute one web view for another and expect things to magically work; loadView will still cause the original blank web view to be your view and to appear in the interface.



    Instead, what you want is this architecture:



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





    share|improve this answer


























    • Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

      – matt
      Jan 2 at 19:19











    • Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

      – cmii
      Jan 8 at 9:56
















    1















    didFinish is called, but the final WKWebView is blank




    Because you never did anything to make it not blank. Your code says:



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


    So everything you do is about webviewToLoad. But webviewToLoad is not the same webView that appears in the ViewController after the segue:



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


    That is the web view you want to give content to. You are not doing that at all; none of your code touches webView to give it content.



    I think the heart of your confusion is here:



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


    You cannot just substitute one web view for another and expect things to magically work; loadView will still cause the original blank web view to be your view and to appear in the interface.



    Instead, what you want is this architecture:



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





    share|improve this answer


























    • Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

      – matt
      Jan 2 at 19:19











    • Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

      – cmii
      Jan 8 at 9:56














    1












    1








    1








    didFinish is called, but the final WKWebView is blank




    Because you never did anything to make it not blank. Your code says:



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


    So everything you do is about webviewToLoad. But webviewToLoad is not the same webView that appears in the ViewController after the segue:



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


    That is the web view you want to give content to. You are not doing that at all; none of your code touches webView to give it content.



    I think the heart of your confusion is here:



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


    You cannot just substitute one web view for another and expect things to magically work; loadView will still cause the original blank web view to be your view and to appear in the interface.



    Instead, what you want is this architecture:



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





    share|improve this answer
















    didFinish is called, but the final WKWebView is blank




    Because you never did anything to make it not blank. Your code says:



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


    So everything you do is about webviewToLoad. But webviewToLoad is not the same webView that appears in the ViewController after the segue:



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


    That is the web view you want to give content to. You are not doing that at all; none of your code touches webView to give it content.



    I think the heart of your confusion is here:



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


    You cannot just substitute one web view for another and expect things to magically work; loadView will still cause the original blank web view to be your view and to appear in the interface.



    Instead, what you want is this architecture:



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






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 2 at 19:18

























    answered Jan 2 at 19:05









    mattmatt

    333k46544742




    333k46544742













    • Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

      – matt
      Jan 2 at 19:19











    • Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

      – cmii
      Jan 8 at 9:56



















    • Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

      – matt
      Jan 2 at 19:19











    • Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

      – cmii
      Jan 8 at 9:56

















    Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

    – matt
    Jan 2 at 19:19





    Please note all of that was just typed in Safari without actually checking in a test app, so if something doesn't work still, let me know.

    – matt
    Jan 2 at 19:19













    Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

    – cmii
    Jan 8 at 9:56





    Hi @matt, My need is to add a loader BEFORE pushing the new viewcontroller with the webview, with your solution, it doesn't work.

    – cmii
    Jan 8 at 9:56













    0














    As @matt's answer was incomplete, here my solution to wait the webview loading before pushing the next view controller:



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

    }


    And the UIViewController with the webview inside:



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


    }
    }


    This code displays an UIAlertController during the webview loading, then dismiss the alert controller, and pushing the next controller, with the webview already loaded.






    share|improve this answer




























      0














      As @matt's answer was incomplete, here my solution to wait the webview loading before pushing the next view controller:



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

      }


      And the UIViewController with the webview inside:



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


      }
      }


      This code displays an UIAlertController during the webview loading, then dismiss the alert controller, and pushing the next controller, with the webview already loaded.






      share|improve this answer


























        0












        0








        0







        As @matt's answer was incomplete, here my solution to wait the webview loading before pushing the next view controller:



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

        }


        And the UIViewController with the webview inside:



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


        }
        }


        This code displays an UIAlertController during the webview loading, then dismiss the alert controller, and pushing the next controller, with the webview already loaded.






        share|improve this answer













        As @matt's answer was incomplete, here my solution to wait the webview loading before pushing the next view controller:



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

        }


        And the UIViewController with the webview inside:



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


        }
        }


        This code displays an UIAlertController during the webview loading, then dismiss the alert controller, and pushing the next controller, with the webview already loaded.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 11 at 10:30









        cmiicmii

        1,76462547




        1,76462547






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54009892%2fhow-to-preload-wkwebview-before-pushing-its-viewcontroller%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith