WKWebView in SwiftUI – How do I switch the view when user interacts with the website?

My situation is the following: I have a SwiftUI application and want to display a WebView. When the user taps a certain button in that WebView I want the user to be redirected to the next (SwiftUI) view.
I use a UIViewRepresentable as this seems to be the current way to go for showing a WebView in SwiftUI because it’s the bridge to UIKit.
The problem is: UIViewRepresentable has no body. So where do I tell the view to switch over? In usual SwiftUI views I would have a model which I’d update and then react on the model change in the body.

I set up an example in which https://www.google.com is rendered in the WebView. When the user sends a search query the coordinator is called which calls a function of the UIViewRepresentable:

View – This is the view that should react on the model changes by displaying another view (implemented with NavigationLinks)

import SwiftUI

struct WebviewContainer: View {
    @ObservedObject var model: WebviewModel = WebviewModel()
    var body: some View {
        return NavigationView {
            VStack {
                NavigationLink(destination: LoginView(), isActive: $model.loggedOut) {
                    EmptyView()
                }.isDetailLink(false)
                .navigationBarTitle(Text(""))
                .navigationBarHidden(self.model.navbarHidden)

                NavigationLink(destination: CameraView(model: self.model), isActive: $model.shouldRedirectToCameraView) {
                    EmptyView()
                }
                .navigationBarTitle(Text(""))
                .navigationBarHidden(self.model.navbarHidden)
                Webview(model: self.model)
            }
        }
    }
}

UIViewControllerRepresentable – This is necessary in order to use the WKWebview in SwiftUI context

import SwiftUI
import WebKit

struct Webview : UIViewControllerRepresentable {
    @ObservedObject var model: WebviewModel

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> EmbeddedWebviewController {
        let webViewController = EmbeddedWebviewController(coordinator: context.coordinator)
        webViewController.loadUrl(URL(string:"https://www.google.com")!)

        return webViewController
    }

    func updateUIViewController(_ uiViewController: EmbeddedWebviewController, context: UIViewControllerRepresentableContext<Webview>) {

    }

    func startCamera() {
        model.startCamera()
    }
}

UIViewController – The WKNavigationDelegate that reacts on the click on “Google Search” and calls the coordinator

import UIKit
import WebKit

class EmbeddedWebviewController: UIViewController, WKNavigationDelegate {

    var webview: WKWebView
    var router: WebviewRouter? = nil

    public var delegate: Coordinator? = nil

    init(coordinator: Coordinator) {
        self.delegate = coordinator
        self.webview = WKWebView()
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        self.webview = WKWebView()
        super.init(coder: coder)
    }

    public func loadUrl(_ url: URL) {
        webview.load(URLRequest(url: url))
    }

    override func loadView() {
        self.webview.navigationDelegate = self
        view = webview
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        guard let url = (navigationResponse.response as! HTTPURLResponse).url else {
            decisionHandler(.cancel)
            return
        }

        if url.absoluteString.starts(with: "https://www.google.com/search?") {
            decisionHandler(.cancel)
            self.delegate?.startCamera(sender: self.webview)
        }
        else {
            decisionHandler(.allow)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Coordinator – Bridge between WKNavigationDelegate and UIViewRepresentable

import Foundation
import WebKit

class Coordinator: NSObject {
    var webview: Webview

    init(_ webview: Webview) {
        self.webview = webview
    }

    @objc func startCamera(sender: WKWebView) {
        webview.startCamera()
    }
}

UPDATE

I now have a View with a model (@ObservedObject). This model is given to the UIViewControllerRepresentable. When the user clicks “Google Search”, UIViewControllerRepresentable successfully calls model.startCamera(). However, this change of the model is not reflected in the WebviewContainer. Why is that? Isn’t that the whole purpose of @ObservedObjects?

Source: Ios