I am attempting to have a list that when a cell it tapped it changes the hasBeenSeen Bool value within the State object itself.
struct State: Identifiable {
    var id = UUID()
    let name: String
    var hasBeenSeen: Bool = false
}
struct ContentView: View {
    let states: [State] = [
        State(name: "Oregon", hasBeenSeen: true),
        State(name: "California", hasBeenSeen: true),
        State(name: "Massachussets", hasBeenSeen: false),
        State(name: "Washington", hasBeenSeen: true),
        State(name: "Georgia", hasBeenSeen: false)
    ]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(states, id: \.id) { state in
                    StateCell(state: state)
                }
            }.navigationBarTitle(Text("States"))
        }
    }
}
struct StateCell: View {
    var state: State
    
    var body: some View {
        HStack {
            Text(state.name)
            Spacer()
            if state.hasBeenSeen {
                Image(systemName: "eye.fill")
            }
        }.onTapGesture {
//            state.hasBeenSeen.toggle()
        }
    }
}
My original thought is that I need to make hasBeenSeen to a @State var but that doesn't seem to work. How can I make this Bool val editable from a list?
                        
Views in SwiftUI are immutable - they are just structures - so you can't change their properties. That's why SwiftUI has a concept of a
@Stateproperty wrapper. When you change "state" property, SwiftUI actually updates the state value, not the view's property value (which is, again, immutable).So, you need to set
@Stateon thestatesproperty within your view. (You'd also need to change the name, since identifierStateis already taken by theStateproperty wrapper - so I just changed it toStateEntity)That's not enough, though, since when you pass an element of the
statesarray (aStateEntityvalue) to a child view, you're just passing a copy.For that, you'd need a binding. A binding allows child views to modify state properties of parent views, without owning the data. So, the child view's property should use the
@Bindingproperty wrapper:SwiftUI made it easy to get the binding of state property by using the projected value, which in this case is
$states.However, you need to pass a binding not to the entire array, but to a specific element of that array. That, unfortunately (and rather annoyingly), is a bit trickier. You need to get the index of the element, and given the index, access the binding like so:
$state[index].One way is to do a
ForEachover indices ofstates: