user9114450
user9114450

Reputation:

SwiftUI: Tabview, keep state when changing tab

I create an application, with several tabs, for each tab there is a webview.

My webview:

struct WebView : UIViewRepresentable {

    let request: URLRequest


    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }

}

The problem when im changing tab, the web view recreate again. I want create the webviews only once, then every time I change tab, it keeped state And webview will not recharge each time

My code:

struct ContentView: View {

    var body: some View {
        TabView {
            WebView(request: URLRequest(url: URL(string: "https://www.google.com/")!))
                    .tabItem {
                        Image(systemName: "1.circle")
                        Text("Messenger")
                    }.tag(0)

            WebView(request: URLRequest(url: URL(string: "https://facebook.com/login")!))
                    .tabItem {
                        Image(systemName: "2.circle")
                        Text("Trello")
                    }.tag(1)
        }
    }

}

Upvotes: 13

Views: 3815

Answers (1)

Asperi
Asperi

Reputation: 258531

Well, SwiftUI views are values, so they are always copied, but WKWebView are objects, so you don't have to re-create them (as you do in UIViewRepresentable) but you can keep reference somewhere once created.

Here is an example code that shows how this could be done. For simplicity of demo I used static, but the cache container can leave wherever suitable.

struct WebView : UIViewRepresentable {

    // static is only for demo, this can be some external model
    static var cache = [URL: WKWebView]()

    let request: URLRequest

    func makeUIView(context: Context) -> WKWebView  {
        guard let url = request.url else { fatalError() }

        if let webView = WebView.cache[url] {
            return webView
        }

        let webView = WKWebView()
        WebView.cache[url] = webView
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        if uiView.url == nil {
            uiView.load(request)
        }
    }

}

Upvotes: 4

Related Questions