首页 > 解决方案 > WKWebView reloads on each segue, instead of maintaining it's last state

问题描述

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:

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.

标签: iosswiftxcodeuiviewcontrollerwkwebview

解决方案


创建一个类型的全局可选变量,WebViewController 并在每个 segue 触发器上检查它是否包含值。

  1. 如果它不包含值,则创建一个实例并将其分配给全局变量并执行 segue。

  2. 如果它包含意味着您WebViewController已经创建和加载的值,只需使用全局实例。

另一种解决方案是使用cache data. 而不是每次都加载页面,而是通过cache data.


推荐阅读