I am trying to use Combine to route SwiftUI views, and it sort of works, but has some unwanted behaviour that I hope someone can help me with. I made an example project which only contains two files, ViewRouter.swift and ViewController.swift that just contains a @IBSegueAction to return a UIHostingController:
The class ViewRouter is a ViewModel for the SwiftUI Views that contains a @ViewBuilder property. When the SwiftUI views calls the didFinish() function, the step property is set to the next View.
class ViewRouter: ObservableObject {
    enum Step { case test1, test2, test3, test4 }
    @Published var step: Step = .test1
    @ViewBuilder var nextStepView: some View {
        switch step {
        case .test1:
            Test1(router: self)
        case .test2:
            Test2(router: self)
        case .test3:
            Test3(router: self)
        case .test4:
            Test4(router: self)
        }
    }
    
    func didFinish() {
        switch step {
        case .test1:
            step = .test2
        case .test2:
            step = .test3
        case .test3:
            step = .test4
        case .test4:
            break
        }
    }
}
This works perfect for Test1, when tapping the Next link, the Test1 view is animated to the left, to reveal Test2. When tapping Next in Test2 however, the Test2 is animated to the left to reveal Test3, but then immediately it animates back to the right to reveal the same Test3 view. Exactly the same happens when tapping Next in Test3.
And tapping the back button always ends up in Test1 view.
All four views are the same, apart from the text in Text:
struct Test1: View {
    @ObservedObject var router: ViewRouter
    @State var nextView = false
    var body: some View {
        VStack {
            NavigationLink(destination: router.nextStepView, isActive: $nextView) {
                EmptyView()
            }
            Text("Test1")
            
            Button(action: {
                nextView = true
                router.didFinish()
            }, label: {
                Text("Next")
            })
        }
    }
}
