Home > Back-end >  Why does my SwiftUI app jump back to the previous view?
Why does my SwiftUI app jump back to the previous view?

Time:01-27

I created an iOS app with SwiftUI and Swift. The purpose is as follows:

  1. User enters an address into an input field (AddressInputView)
  2. On submit, the app switches to ResultView and passes the address

Problem: The ResultView is visible for just a split second and then suddenly jumps back to AddressInputView.

Question: Why is the app jumping back to the previous view (Instead of staying in ResultView) and how can the code be adjusted to fix the issue?

My Code:


StartView.swift

struct StartView: View {
    var body: some View {
        NavigationStack {
            AddressInputView()
        }
    }
}

AddressInputView.swift

enum Destination {
    case result
}

struct AddressInputView: View {
    @State private var address: String = ""
    @State private var experiences: [Experience] = []
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            VStack {
                TextField("", text: $address, prompt: Text("Search address"))
                    .onSubmit {
                        path.append(Destination.result)
                    }
                Button("Submit") {
                    path.append(Destination.result)
                }
                .navigationDestination(for: Destination.self, destination: { destination in
                    switch destination {
                        case .result:
                            ResultView(address: $address, experiences: $experiences)
                    }
                })
            }
        }
    }
}

ExperienceModels.swift

struct ExperienceServiceResponse: Codable {
    let address: String
    let experiences: [Experience]
}

ResultView.swift

struct ResultView: View {
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    @Binding private var address: String
    @Binding private var experiences: [Experience]

    init(address: Binding<String>, experiences: Binding<[Experience]>) {
        _address = Binding(projectedValue: address)
        _experiences = Binding(projectedValue: experiences)
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(alignment: .leading) {
                    Text("Results")
                    ForEach(experiences, id: \.name) { experience in
                        ResultTile(experience: experience)
                    }
                }
            }
        }
    }
}

CodePudding user response:

You have too many NavigationStacks. This is a container view that should be containing your view hierarchy, not something that is declared at every level. So, amend your start view:

struct StartView: View {
    
    @State private var path = NavigationPath()
    var body: some View {
        NavigationStack(path: $path) {
            AddressInputView(path: $path)
        }
    }
}

AddressInputView should take the path as a binding:

@Binding var path: NavigationPath

And you should remove NavigationStack from the body of that view. Likewise with ResultView. I made these changes in a project using the code you posted and the issue was fixed.

I'm not sure exactly why your view is popping back but you're essentially pushing a navigation view onto a navigation view onto a navigation view, so it's not entirely surprising the system gets confused.

  • Related