skip to Main Content

I have a EditTapasView which is there to edit any Tapas created by the user. To create one, they can press a "New Tapas" button, sending them to exactly this EditTapasView with a newly created Tapas.

Until now it all worked with using a sheet.

Button(action: {
    newTapas = addTapas()
    /// Delay the toggle of the Sheet by .1 second.
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
         shouldPresentSheet.toggle()
    }
}, label: {
    Text("New Tapas")
        .font(.system(size: 17))
        .padding(.trailing)
        .padding([.top, .bottom], 10)
})
   .sheet(isPresented: $shouldPresentSheet) {
       print("Sheet dismissed!")
    } content: {
       EditTapasView(tapas: newTapas)
    }

But now I have added a new NavigationLink inside of the EditTapasView to make some edits, and this part is not working in a sheet.

When I just use a NavigationLink and giving it the addTapas() function, it constantly creates new Tapas without any click.

NavigationLink(destination: EditTapasView(tapas: addTapas())) {
    Text("New Tapas")
        .font(.system(size: 17))
        .padding(.trailing)
        .padding([.top, .bottom], 10)
}

Then I researched how to navigate progamatically, but I couldn’t make it work.

NavigationStack (path: $path) {
    Button(action: {
        newTapas = addTapas()
        path = EditTapasView(tapas: newTapas)
    }, label: {
        Text("New Tapas")
            .font(.system(size: 17))
            .padding(.trailing)
            .padding([.top, .bottom], 10)
    })
}

So is there any way to solve my problem? Either to simply use NavigationLink (or similar) in the Action part of a button? Or to have some logic execute once a NavigationLink is pressed?

2

Answers


  1. There’s probably a few different ways a simple way would be to use navigationDestination if it’s not too buggy. The NavigationStacks and NavigationSplitViews aren’t really ready for production yet.

    @State private var newTapa: Tapa?
    
    var body: some View {
            NavigationStack {
                Button("Add Tapas") {
                    newTapa = Tapa()
                }
                .navigationDestination(item: newTapa) { tapa in
                    TapaEditView(tapa: tapa)
                }
            }
    }
    
    Login or Signup to reply.
  2. NavigationPath is correct for programatic navigation, just need to change it to this:

    NavigationStack (path: $path) {
        Button(action: {
            let newTapas = newTapas()
            path = [newTapas]  // this calls navigationDestination
        }, label: {
            Text("New Tapas")
                .font(.system(size: 17))
                .padding(.trailing)
                .padding([.top, .bottom], 10)
        })
        .navigationDestination(item: newTapas) { newTapas in
            EditTapasView(tapas: newTapas)
        }
    }
    

    And your Tapas model type needs to be a class in this case.

    Note in your first attempt that uses DispatchQueue, you can’t use asyncAfter in SwiftUI because the Views are just structs, i.e. values that have no lifetime. After the UI has been described the Views are gone.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search