1

In the SwiftUI, how could I create two separate instances of the same struct? The purpose for this, in my case, is the following: I have an application written in the SwiftUI consisting of a tab bar. Each tab shows a different webpage. When I create the tab bar, for each tab object, I am currently passing a URLrequest as an argument of a struct. However, I have had to make a new struct with nearly the same code verbatum for each webpage/tab I want. When I try to just use the same struct, all tabs show the same webpage due to the first line of the struct:

static var cache = [URL: WKWebView]()

However, if I remove the static keyword, I just unresolvable errors. How can I do this successfully?

Ok, here's my continuation for the requested example. Here's the struct which controls the webview.

struct WebView : UIViewRepresentable {
    
    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)
        }
    }
}

Now here's the contentview:

struct ContentView: View {
    var body: some View {
        TabView {
            WebView(request: URLRequest(url: URL(string: "https://www.google.com")!)).edgesIgnoringSafeArea(.all).tabItem {
                VStack {
                    Text("Google")
                }
            }
            
            WebView(request: URLRequest(url: URL(string: "https://www.apple.com")!)).edgesIgnoringSafeArea(.all).tabItem {
                VStack {
                    Text("Apple")
                }
            }
        }
    }
}

However, this would cause both tabs to always show the same page. I clearly want them to show the urls specified. How might I accomplish this?

0

1 Answer 1

1

Try the following:

struct ContentView: View {
    var body: some View {
        TabView {
            webView(url: "https://www.google.com")
                .edgesIgnoringSafeArea(.all)
                .tabItem {
                    VStack {
                        Text("Google")
                    }
                }
            webView(url: "https://www.apple.com")
                .edgesIgnoringSafeArea(.all)
                .tabItem {
                    VStack {
                        Text("Apple")
                    }
                }
        }
    }

    func webView(url: String) -> some View {
        WebView(request: URLRequest(url: URL(string: url)!))
    }
}

Note: instead of force-unwrapping URL(string: url)! you may want to provide a default url or a default view. Even if the site is valid it may not always be available.

Sign up to request clarification or add additional context in comments.

7 Comments

Works for me - I tested it using Xcode 11.5, Swift 1.0. If it doesn't maybe it's because you're using Swift 2.0 beta. In that case you should specify it in the question.
I'm not sure how to check which version I'm using. How can I find this?
@R12568asdb You can start with the Xcode version: Go to Xcode -> About Xcode
11.5 is my current Xcode version, but I knew that one
Ah, nevermind, there's just some unknown problem with the Mac. I just simulated it on my physical iPhone and it works great. Thanks!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.