3

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 3

2
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
}
Sign up to request clarification or add additional context in comments.

3 Comments

wau, this works. I do admit though that I do not understand what the Bindingwrapper is doing and why.
researching your use of UUID I found this helpful video hackingwithswift.com/books/ios-swiftui/…. I am getting closer to understand what you have done
Can you explain what this is doing?
1
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])
                }
            }
        }
    }
}

3 Comments

Your answer is more likely to be well received (and therefore upvoted) if it's formatted properly. Also try to add some explanation of your code.
I think this works for one variable with different values , but what I am after is to have multiple @State variable in a ForEach loop
in my code mainPrice is not one variable! it is an array of data, in your way and in your accepted Answer you are limiting your self just for 2 variable, but in my version of coding, you can have as much as variable you want, you can have 0 variable to thousands! which your way fails if you got more than 2 variables, with my code you just simply append new data to existed one.
0

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)
         }
     }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.