Search code examples
swiftuiswiftui-navigationlink

SwiftUI - NavigationLink creating new item and navigating to the new view


How can I modify my code so that when the user taps the "plus.app.fill" button, they are directly taken to the subview of the newly created flight? Below is the code that I'm currently using:

struct FlightsOverView: View {
    
    @ObservedObject var viewModel : FlightVM
    
    var body: some View {
        NavigationStack{
            List {
                ForEach(viewModel.flights, id: \.id) { flight in
                    ZStack {
                        NavigationLink(destination: FlightDetailView(flight: flight, viewModel: viewModel), label: {
                            FlightCell(flight: flight)
                                .listRowInsets(EdgeInsets(top: 5, leading: 8, bottom: 5, trailing: 8))
                        }).opacity(0)
                        FlightCell(flight: flight)
                            .listRowInsets(EdgeInsets(top: 5, leading: 8, bottom: 5, trailing: 8))
                    }
                }
                .onDelete(perform: viewModel.removeFlight)
            }
            .listStyle(PlainListStyle())
            .navigationTitle("Flights")
            .toolbar(content: {
                Button("\(Image(systemName: "plus.app.fill"))", action: {
                    let flight = viewModel.createNewFlight()
                    viewModel.addFlight(flight: flight)
                })
            })
        }
    }

}

At the moment when the "plus.app.fill" is tapped it creates a new empty flight but I would also like to navigate to the new subview. I tried "isActive" and other suggestions here but these were deprecated in iOS 16.0 "'init(destination:isActive:label:)' was deprecated in iOS 16.0: use NavigationLink(value:label:) inside a NavigationStack or NavigationSplitView"


Solution

  • Bind an array of Flights to the NavigationStack as its navigation path. Then you can just add the newly created Flight to the path to navigate there.

    Assuming Flight conforms to Hashable

    @State var navigationPath: [Flight] = []
    
    NavigationStack(path: $navigationPath) {
        List {
            ...
        }
        .navigationDestination(for: Flight.self) { flight in
            FlightDetailView(flight: flight, viewModel: viewModel)
        }
    }
    

    In the ForEach, pass each flight to the NavigationLink:

    NavigationLink(value: flight) {
        // build the label here...
    }
    

    When adding a new flight,

    let flight = viewModel.createNewFlight()
    viewModel.addFlight(flight: flight)
    navigationPath.append(flight)