'SwiftUI ToolbarItem doesn't present a View from a NavigationLink

I don't know if this is a bug or I am doing something wrong here. I've added a new button on the Navigation bar that would present a new view.

struct MyView: View {
  
  @ObservedObject var viewModel = MyViewModel()
  
  var body: some View {
    List(viewModel.data, id: \.name) { data in
      NavigationLink(destination: MyDetailView(data: data.name)) {
        Text(data.name)
      }
    }
    .listStyle(InsetGroupedListStyle())
    .edgesIgnoringSafeArea(.all)
    .toolbar {
      ToolbarItem(placement: .navigationBarTrailing) {  
        NavigationLink(destination: MyDetailView()) {
          Text("New Element")
        }
      }
    }
  }
}

This is being tested on the newest iOS 14 beta (beta 6) and Xcode 12 (beta 6). As far as I know a Navigation Link presents fine the new view when on a List but in the toolbar as shown that's not the case. The button on the toolbar it's visible and active but doesn't trigger showing the new view.



Solution 1:[1]

NavigationLink should be inside NavigationView. Toolbar is not in NavigationView, put buttons in it.

So assuming you have somewhere in parent

NavigationView {
   MyView()
}

here is a solution:

struct MyView: View {
  
  @ObservedObject var viewModel = MyViewModel()
  @State private var showNew = false

  var body: some View {
    List(viewModel.data, id: \.name) { data in
      NavigationLink(destination: MyDetailView(data: data.name)) {
        Text(data.name)
      }
    }
    .listStyle(InsetGroupedListStyle())
    .background(
        NavigationLink(destination: MyDetailView(), isActive: $showNew) {
          EmptyView()
        }
    )
    .edgesIgnoringSafeArea(.all)
    .toolbar {
      ToolbarItem(placement: .navigationBarTrailing) {  
        Button("New Element") {
            self.showNew = true
        }
      }
    }
  }
}

backup

Solution 2:[2]

I found using an HStack with an empty text as the first element also works, it lets the navigationLink act correctly.

        .toolbar {
        ToolbarItem(placement: .navigationBarLeading) {
            HStack {
                Text("")
                NavigationLink(destination: SettingsView()) {
                    Image(systemName: "gear")
                        .font(.title)
                }
            }
        }

Solution 3:[3]

Using Asperi solution may not work if your navigation link directs to a view with keyboard input.

After navigation link, toolbar in the new view loaded correctly but when providing input with keyboard and dismissing keyboard all toolbar items disappears.

The solution is to place NavigationLink not in View but in navigationBarItems, example:

.navigationBarItems(
                leading:
                    NavigationLink(
                        destination: Creator(),
                        isActive: $showCreator,
                        label: {
                            Text("")
                        }))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 FBronner
Solution 3 akuba