Cannot get the @state variable in a ForEach loop working with SwiftUI

Viewed 968

I want to produce a list of input TextFields with a ForEach loop. The textFields are obviously @State variables.

I do get the error:

Generic struct 'ForEach' requires that 'Binding' conform to 'Hashable'

Here is my code:

struct ContentView: View {
    @State private var mainPrice = ""
    @State private var mainGrade = ""
    
    var body: some View {
        
        var inputFields = [$mainPrice,$mainGrade]
        
        HStack {
            List{
                ForEach(inputFields, id: \.self)  { value in   /// here is the error

                    TextField("Enter data", text: value)

                    }
                }
        }
       
    }

So, I am putting the binding variables in an array since I need a binding type in the loop, maybe that is not how to do this? I tried to add Hashable to the inputFields var to respond to the error message, but I am suspecting the whole setup is wrong.

3 Answers
import SwiftUI

struct ContentView: View {
    @State private var mainPrice = ""
    @State private var mainGrade = ""
    
    var body: some View {
        
        let inputFields = [BindingWrapper(binding: $mainPrice), BindingWrapper(binding: $mainGrade)]
        
        HStack {
            List{
                ForEach(inputFields, id: \.uuid)  { value in   /// here is the error
                    TextField("Enter data", text: value.$binding)

                }
            }
        }
    }
}

struct BindingWrapper {
    let uuid: UUID = UUID()
    @Binding var binding: String
}
struct ContentView: View {
    @State private var mainPrice = ["1000", "5000"]

    var body: some View {
        HStack {
            List {
                ForEach(mainPrice.indices, id: \.self) { index in
                    TextField("Enter data", text: $mainPrice[index])
                }
            }
        }
    }
}

I actually found another way of doing this with a struct that has an id since the main issue seems to be that the array does not provide an exact identification of data. We need an id (see video https://www.hackingwithswift.com/books/ios-swiftui/working-with-identifiable-items-in-swiftui):

struct tableContent{
    var id: Int
    var label: String
    var data: Binding<String>
}

The array would look like this:

let textFields = [
            tableContent(id: 1, data: $mainPrice),
            tableContent(id: 2, data: $mainGrade)
        ]

And the ForEach loop

List{
     ForEach(textFields, id: \.id)  { value in
         TextField("", text: value.data)
         }
     }
Related