Nicola Rigoni
Nicola Rigoni

Reputation: 241

new navigation stack swiftui 4

Hello I'm using the new navigation stack and I don't really understand how it works in a situation like mine. I have the first view (DashboardView) from there I have two navigationdestination(isPresented) and from the second one I have to go a view (AllVocabulariesView) with a list and after every row has to go to another view (VocabularyView) that is the save that I can reach from the DashboardView with the first navigationdestination(isPresented).

here below the DashboardView (I remove unnecessary code)

NavigationStack {
VStack {
LazyVGrid(columns: columns, alignment: .center, spacing: spacing, pinnedViews: [])
                {
                    ForEach(vmHome.vocabularies.prefix(5)) { vocabulary in
                        
                        VocabularyBannerView(name: vocabulary.name ?? "", language: vmHome.getLanguageName(code: vocabulary.language ?? ""), isFavourite: vocabulary.isFavourite)
                            .onTapGesture {
                                selectedVocabulary = vocabulary
                                showVocabularyView.toggle()
                            }
                            .contextMenu {
                                Button {
                                    vmHome.setVocabularyAsFavourite(entity: vocabulary)
                                } label: {
                                    Label("Favourite", systemImage: "star")
                                }
                                
                                Button(role: .destructive) {
                                    vmHome.deleteVocabulary(vocabulary: vocabulary)
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }

                            } preview: {
                                VocabularyBannerView(name: vocabulary.name ?? "", language: vmHome.getLanguageName(code: vocabulary.language ?? ""), isFavourite: vocabulary.isFavourite)
                            }
                        
                    }
                }

Button {
                        showAllVocabularyView.toggle()
                    } label: {
                        Text("Show all")
                            .font(.caption)
                    }
}
.navigationTitle("Dashboard")
.toolbar(.hidden, for: .navigationBar)
            .navigationDestination(isPresented: $showVocabularyView) {
                if selectedVocabulary != nil {
                    VocabularyView(vmHome: vmHome, vocabulary: selectedVocabulary!)
                }
            }
            .navigationDestination(isPresented: $showAllVocabularyView) {
                AllVocabulariesView(vmHome: vmHome)
            }
}

so the first one goes to the VocabularyView and it's fine also the second goest to AllVocabulariesView but now the problem is inside the AllVocabulariesView that I have structured like this

NavigationStack{
            List {
                ForEach(vmHome.vocabularies) { vocabulary in
                    NavigationLink(value: vocabulary) {
                        Text(vocabulary.name ?? "")
                    }
                }
            }
            .navigationDestination(for: VocabularyEntity.self, destination: { vocabulary in
                VocabularyView(vmHome: vmHome, vocabulary: vocabulary)
            })
            .navigationTitle("Your vocabularies")
            .navigationBarTitleDisplayMode(.inline)
        }

two thinks if I remove the navigationstack the row has being highlighted but nothing happen and with navigationstack it goest to the view but without animation and the back button goest back to DashboardView instead of AllVocabulariesView

Upvotes: 0

Views: 257

Answers (1)

Adkarma
Adkarma

Reputation: 43

After testing in several applications, I have come to the conclusion that NavigationStack should not be nested.

In fact, you can use the .navigationDestination at the top level and it will keep working for all nested NavigationLink.

Although I cannot test without the full code, I suggest you do the following modifications:

  • Remove the NavigationStack from your AllVocabulariesView
  • Group your .navigationDestination at the top level where you have put the other ones

DashboardView:

NavigationStack {
VStack {
LazyVGrid(columns: columns, alignment: .center, spacing: spacing, pinnedViews: [])
                {
                    ForEach(vmHome.vocabularies.prefix(5)) { vocabulary in
                        
                        VocabularyBannerView(name: vocabulary.name ?? "", language: vmHome.getLanguageName(code: vocabulary.language ?? ""), isFavourite: vocabulary.isFavourite)
                            .onTapGesture {
                                selectedVocabulary = vocabulary
                                showVocabularyView.toggle()
                            }
                            .contextMenu {
                                Button {
                                    vmHome.setVocabularyAsFavourite(entity: vocabulary)
                                } label: {
                                    Label("Favourite", systemImage: "star")
                                }
                                
                                Button(role: .destructive) {
                                    vmHome.deleteVocabulary(vocabulary: vocabulary)
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }

                            } preview: {
                                VocabularyBannerView(name: vocabulary.name ?? "", language: vmHome.getLanguageName(code: vocabulary.language ?? ""), isFavourite: vocabulary.isFavourite)
                            }
                        
                    }
                }

Button {
                        showAllVocabularyView.toggle()
                    } label: {
                        Text("Show all")
                            .font(.caption)
                    }
}
.navigationTitle("Dashboard")
.toolbar(.hidden, for: .navigationBar)
            .navigationDestination(isPresented: $showVocabularyView) {
                if selectedVocabulary != nil {
                    VocabularyView(vmHome: vmHome, vocabulary: selectedVocabulary!)
                }
            }
            .navigationDestination(isPresented: $showAllVocabularyView) {
                AllVocabulariesView(vmHome: vmHome)
            }
            .navigationDestination(for: VocabularyEntity.self, destination: { vocabulary in
                VocabularyView(vmHome: vmHome, vocabulary: vocabulary)
            })
}

AllVocabulariesView:

 List {
     ForEach(vmHome.vocabularies) { vocabulary in
         NavigationLink(value: vocabulary) {
             Text(vocabulary.name ?? "")
         }
     }
  }
  .navigationTitle("Your vocabularies")
  .navigationBarTitleDisplayMode(.inline)

Upvotes: 1

Related Questions