I've read all previous posts on this topic but none seem to address what I'm seeing for iOS 16 and using NavigationStack. I'm also using an overall @EnvironmentObject for navigation state.
I have a split view app. In the detail section, I have a NavigationStack surrounding the detail view. Within the detail view (MyView), there is a base view with a "+" button in the toolbar to create a new entity.
That opens NewEntityView where I show a grid of buttons for the user to select a type to create a new entity before moving to NewEntityView to fill in the details for the entity. The top row of the grid of buttons takes the user straight to the NewEntityView with a NavigationLink. These work fine.
The next row of buttons present a menu of sub-types and then should take the user to the NewEntityView view. These buttons do not work.
Code (simplified to not have clutter):
SplitViewDetailView:
struct SplitViewDetailView: View {
@EnvironmentObject var navigationManager: NavigationStateManager
@Binding var selectedCategory: Route?
var body: some View {
NavigationStack(path: $navigationManager.routes) {
// other irrelevant stuff
MyView()
}
.environmentObject(navigationManager)
.navigationDestination(for: Route.self) { $0 }
}
}
MyView:
struct MyView: View {
@EnvironmentObject var navigationManager: NavigationStateManager
var body: some View {
List {
// other stuff
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {}, label: {
NavigationLink(value: Route.newTypeSelect) {
Image(systemName: "plus")
.frame(width: 44, height: 44)
}
} )
}
}
.navigationDestination(for: Route.self) { $0 }
}
SelectTypeView:
struct SelectTypeView: View {
var body: some View {
ZStack {
VStack {
// Top row with no subtypes
HStack {
ForEach (topRows, id: \.self) { type in
NavigationLink(value: Route.newEntityDetails(type.rawValue)) { <-- these work
Text(type)
}
}
}
HStack {
ForEach (middleRow, id: \.self) { type in
Menu {
ForEach (subtype[type], id: \.self) { sub in
NavigationLink(value: Route.newEntityDetails(sub.rawValue)) { <-- these go nowhere
Text(sub)
}
}
} label: {
Text(type)
}
}
}
}
}
}
}
NavigationStateManager:
class NavigationStateManager: ObservableObject {
@Published var routes = [Route]()
// other stuff
}
And Route:
enum Route: Identifiable {
var id: UUID { UUID() }
case newTypeSelect
case newEntityDetails(String)
}
extension Route: View {
var body: some View {
switch self {
case .newTypeSelect:
SelectTypeView()
case .newEntityDetails(let type):
NewEntityView(selectedType: type)
}
}
}
The menus show up fine but tapping on an item does nothing. I've attempted to wrap the menu in its own NavigationStack but that is rejected stating it is already in one defined by a parent view. I've tried making the links Buttons with destinations and those are also rejected.
What is the newest/best way to present a menu with NavigationLinks? One doesn't simply wrap the menu in a NavigationView if one is using a NavigationStack?