Search code examples
iosswiftswiftuiswiftui-listswiftui-navigationlink

Picker conflicts with NavigationLink gesture


I am trying to create the following card view.

Screenshot of card

With the following code to achieve it.

struct SimpleGame: Identifiable, Hashable {
    var id = UUID()
    let name: String
}

enum PlayingStatus: String {
    case In = "I"
    case Out = "O"
    case Undecided = "U"
}


struct TestView: View {
    let games: [SimpleGame] = [
        .init(name: "First"),
        .init(name: "Second")
    ]
    
    @State private var currentStatus: PlayingStatus = .Undecided
    
    var body: some View {
        NavigationView {
            List(games) { game in
                Section {
                    VStack {
                        NavigationLink(value: game) {
                            Text("\(game.name)")
                        }
                        Divider()
                        Picker("Going?", selection: $currentStatus) {
                            Text("No Response")
                                .tag(PlayingStatus.Undecided)
                            Text("Going")
                                .tag(PlayingStatus.In)
                            Text("Not going")
                                .tag(PlayingStatus.Out)
                        }
                            .font(.body)
                    }
                }
            }
            .navigationDestination(for: Game.self) { game in
                Text("Detail View")
            }
            .listStyle(InsetGroupedListStyle())
            .navigationTitle("Upcoming")
        }
    }
}

But a tap on element wrapped by NavigationLink is registering as a tap on the Picker. Anyone know of a way around this?

iOS 16/Xcode 14


Solution

  • you could try this:

    List {
        ForEach(games, id: \.name) { game in
            Section {
                NavigationLink(value: game) {
                    Text("\(game.name)")
                }
                // -- here
                VStack {
                    Divider()
                    Picker("Going?", selection: $currentStatus) {
                        Text("No Response").tag(PlayingStatus.Undecided)
                        Text("Going").tag(PlayingStatus.In)
                        Text("Not going").tag(PlayingStatus.Out)
                    }
                    .font(.body)
                }
            }
        }
    }