Search code examples
swiftuiios-navigationviewswiftui-14.2-defect

NavigationLink tag and selection not working as expected


I am probably missing something but I can't make the NavigationLink work inside a List.
I'm using NavigationLink(destination, tag, selection) And i would like to pop to the root view with a tap on a button as you can see in this sample project:

import SwiftUI

struct ContentView: View {
    @State var selectedView: Int? = nil
    var colors: [String] = ["blue", "yellow", "green", "red", "black"]
    
    var body: some View {
        NavigationView {
            List{
                ForEach(colors.indices) { index in
                    NavigationLink(
                        destination: ColorDetail(selectedView: self.$selectedView, color: colors[index]),
                        tag: index,
                        selection: self.$selectedView,
                        label: {
                            Text(colors[index])
                        })
                }
            }
        }
    }
}

struct ColorDetail: View {
    
    @Binding var selectedView: Int?
    var color: String
    
    var body: some View {
        VStack {
            Text(color)
            Text("SelectedView: \(selectedView ?? 99)")
            Button("set SelectedView to nil and go back") {
                self.selectedView = nil
            }
        }
    }
}

Why if I set selectedView to nil nothing happens? How can i pop to the root view (ContentVIew) from the ColorDetail on a button tap?

Just copy this code and try it, it will build.


Solution

  • As Asperi says, looks like a bug in 14.2 as it should really work setting it to nil. However, if you need a workaround which should work in all version try using presentationMode

    struct ColorDetail: View {
        
        @Binding var selectedView: Int?
        var color: String
        @Environment(\.presentationMode) var presentationMode
    
        var body: some View {
            VStack {
                Text(color)
                Text("SelectedView: \(selectedView ?? 99)")
                Button("set SelectedView to nil and go back") {
                    self.selectedView = nil
                    self.presentationMode.wrappedValue.dismiss()
                }
            }
        }
    }