0

I currently have two ViewControllers:

  1. ViewController: The welcome/dashboard view.
  2. WebViewController: The view that gets passed URLs to load in a WKWebView.

Here is my situation: I have a number of objects in my ViewController (mostly UIButtons and UIBarButtonItems), each with it's own unique URL, that will then segue (Show/Push) that object's specific URL to the WebViewController and load said URL in the WKWebView.

However, when loading the same URL (which I have implemented a check for), the WKWebView will still reload the page each time that same URL is requested. When pushed to WebViewController with the same URL that was loaded prior, the WKWebView will:

  • Display the page it had loaded prior for half a second
  • Flash white while it attempts to reload
  • And then reloads that exact same URL

I simply want the WebViewController's WKWebView to maintain its already-loaded state if the requested URLs are the same.

ViewController.swift

@IBAction func goDashboard(_ sender: UIButton) {
    Page.query = Page.dashboard
    performSegue(withIdentifier: "WebViewSegue", sender: nil)
}
@IBAction func goNewProject(_ sender: UIButton) {
    Page.query = Page.newProject
    performSegue(withIdentifier: "WebViewSegue", sender: nil)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "WebViewSegue" {
        let webVC = segue.destination as! WebViewController
        webVC.query = Page.query
    }
}

WebViewController.swift

var query = URL(string: Client.url)     // Default value
@IBOutlet weak var webView: WKWebView!

override func viewDidLoad() {
    super.viewDidLoad()
    
    if debug { print("Loading URL: \(String(describing: query))") }

    webView.uiDelegate = self
    webView.navigationDelegate = self
    webView.customUserAgent = Client.userAgent              // Set Client UserAgent
    // WebView Configuration
    let config = webView.configuration
    config.applicationNameForUserAgent = Client.userAgent   // Set Client Name
    config.preferences.javaScriptEnabled = true             // Enable JavaScript
    // ScrollView Setup
    webView.scrollView.delegate = self
    webView.scrollView.isScrollEnabled = true               // Enable Scroll
    webView.scrollView.keyboardDismissMode = .onDrag        // Hide Keyboard on WebView Drag
    //showScroll(false, bounce: true)                       // Hide Scroll, Enable Bounce
    webView.scrollView.alwaysBounceHorizontal = false
    webView.scrollView.showsHorizontalScrollIndicator = false
    
    if !Page.isSame() {
        print("Queries are different, load new page")
        webView.load((query ?? Page.dashboard)!)
    } else {
        print("Queries are the same, DON'T RELOAD!")
    }
}

EDIT: I have also tried stopping the data from passing between the ViewController's if the URLs match.

if segue.identifier == "WebViewSegue" {
    if !Page.isSame() {
        let webVC = segue.destination as! WebViewController
        webVC.query = Page.query
    }
}

EDIT 2: I have also attempted to get rid of the prepare segue.identifier and, instead, added the check to WebViewController using global variables. It still reloads each time.

JDev
  • 5,168
  • 6
  • 40
  • 61

1 Answers1

0

Create one global optional variable of type WebViewController and on each segue trigger check if it contains value or not.

  1. If it don't contains value then create one instance and assign it to the global variable and perform segue.

  2. if it contains the value that means your WebViewController is already created and loaded, just utilise global instance.

Another solution would be use of cache data. Instead of loading page every time, load it through cache data.

Jarvis The Avenger
  • 2,750
  • 1
  • 19
  • 37