I’m using UIHostingController in order to present a SwiftUI flow (more or less 5 screens) inside a UIKit based app. But at the end of the SwiftUI flow, I need to return to the last ViewController presented. Does anyone know how to accomplish that behavior?
To put the problem in simple words:
Screen A (UIViewController) -> Screen B (SwiftUI view) -> Screen C (SwiftUI view) -> Screen D (SwiftUI view). Screen D needs to return to Screen A.
Notes:
- SwiftUIviews use- NavigationViewand- NavigationLink's.
- I looked at https://stackoverflow.com/a/61926030/6938899 but the answer solves the problem to return to Screen B (still a SwiftUIview).
EDIT
Added simplified version in code to explain the problem better:
import UIKit
import SwiftUI
// MARK: - Wrapper to use SwiftUI views inside UIKit
class SwiftUIWorkflowViewController: UIHostingController<SwiftUIWorkflowView> {
    
    override init(rootView: SwiftUIWorkflowView) {
        super.init(rootView: rootView)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
}
// MARK: - ViewModel for SwiftUI workflow
public final class SwiftUIWorkflowViewModel: ObservableObject { }
// MARK: - UIKit screen
class ScreenAViewController: UIViewController {
    
    //... other stuff
    
    private func navigateToSwiftUIFlow() {
        let swiftUIWorkflowViewModel = SwiftUIWorkflowViewModel()
        let deviceNetworkingVC = SwiftUIWorkflowViewController(
            rootView: SwiftUIWorkflowView(viewModel: swiftUIWorkflowViewModel)
        )
        navigationController?.pushViewController(deviceNetworkingVC, animated: true)
    }
}
// MARK: - Beggining of SwiftUI views
public struct SwiftUIWorkflowView: View {
    
    @Environment(\.presentationMode) private var presentationMode
    @ObservedObject var viewModel: SwiftUIWorkflowViewModel
    
    // MARK: - Init
    public init(viewModel: SwiftUIWorkflowViewModel) {
        self.viewModel = viewModel
    }
    
    // MARK: - Views
    public var body: some View {
        NavigationView {
            ScreenBView(onBack: { self.presentationMode.wrappedValue.dismiss() })
        }
        .environmentObject(self.viewModel)
    }
}
// MARK: - Screen B (SwiftUI)
public struct ScreenBView: View {
    
    @EnvironmentObject var viewModel: SwiftUIWorkflowViewModel
    
    var onBack: (() -> Void)? = nil
    
    public init(onBack: (() -> Void)? = nil) {
        self.onBack = onBack
    }
    
    public var body: some View {
        VStack {
            Text("Screen B")
            Button {
                self.onBack?()
            } label: {
                Text("Go back to UIKit screen")
            }
            NavigationLink(destination: ScreenBView()) {
                Text("Go to screen C")
            }
        }
    }
    
}
// MARK: - Screen C (SwiftUI)
public struct ScreenCView: View {
    
    @EnvironmentObject var viewModel: SwiftUIWorkflowViewModel
    
    public var body: some View {
        VStack {
            Text("Screen C - End of the SwiftUI flow!")
            // here I need a way to return to ScreenAViewController.
        }
    }
    
}
