Search code examples
swiftswiftuiwkwebview

Hiding view when WKWebView has finished loading swiftUI


I'm trying to hide the launch screen once the WKWebView finshes loading. I've found a way to detect when the WKWebView has finished loading with the didFinish delegate, but I'm stuck on hiding the launch screen. At the moment, it sets the webViewFinishedLoading to true once WKWebView has finished loading, and in ContentView.swift, It should only show the view if webViewFinishedLoading is set to false. But right now it only shows the launch screen even after WKWebView finishes loading. Here's my code:

ContentView.swift:

var webViewFinishedLoading = false
struct ContentView: View {
    var body: some View {
       SwiftUiWebView(url: URL(string: "myUrl"))
       ZStack {
          if (!webViewFinishedLoading) {
             ....
          }
       }
    }
}

WebView.swift

....
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    if (webView.isLoading) {
       return
    }
    print("Done Loading")
    webViewFinishedLoading = true
}
....

I know that didFinish gets called because I see "Done Loading" in my debug console.


Solution

  • Your View won't know to reload unless it is triggered with something like a @State property or an ObservableObject. You haven't really provided enough code from your SwiftUiWebView to show everything, but here's the gist of what needs to happen:

    struct ContentView: View {
        @State var webViewFinishedLoading = false
    
        var body: some View {
           SwiftUiWebView(url: URL(string: "myUrl"), finishedLoading: $webViewFinishedLoading)
           ZStack {
              if (!webViewFinishedLoading) {
                 ....
              }
           }
        }
    }
    
    struct SwiftUiWebView : UIViewRepresentable {
      var url: URL
      var finishedLoading: Binding<Bool>
    
      //...
    } 
    

    Then, you will need to pass that finishedLoading Binding to your web view delegate and set its .wrappedValue to true when you're done loading:

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if (webView.isLoading) {
           return
        }
        print("Done Loading")
        finishedLoading.wrappedValue = true
    }
    

    Because it's tied to a @State variable, your view will know to refresh.