1

I am new to SwiftUI and there is a scenario in which I can add more than one person's data and every time I tap on the button, it will collect new person's data.

The scenario is like this: scenario

I add data on one textfield, it updates on every textfield because there is only one state variable for the textfield. My problem is how can I add multiple State variables for the textfield as the textfields have no fixed number. My code is:



import SwiftUI

struct TextFieldText: View {
    
    @State private var name = ""
    @State private var email = ""
    @State var totalValue: Int = 1
    
    var body: some View {
        
        VStack(spacing: 30) {
            
            ForEach((1...totalValue).reversed(), id: \.self) {_ in

                VStack {
                    CustomTextfield(text: $name, placeHolder: "Enter name", title: "Enter Name")
                    
                    CustomTextfield(text: $email, placeHolder: "Enter email", title: "Enter Email")
                }
            }
            
            Button {
                print("add person tapped")
                totalValue = totalValue + 1
            } label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 60)
                        .frame(width: 180, height: 45)
                        .foregroundColor(Color(ColorName.appBlue.rawValue))
                    Text("Add another person")
                        .foregroundColor(.white)
                        .font(Font.custom(InterFont.bold.rawValue, size: 14))
                }
            }
            Spacer()
        }
        
    }
}

struct TextFieldText_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldText()
    }
}

I want to add different data on every textfield. How can I achieve it in SwiftUI?

Taimoor Arif
  • 750
  • 3
  • 19
  • Use arrays if names and emails. You need to have different state variables for each text field. – Ptit Xav Apr 25 '22 at 09:20
  • You don't really. I would have a List (and an array) under the button so when you press the button the values you have entered is added to the array and shown in the list and at the same time the fields are cleared so you can enter a new person. I would also consider creating a struct for person that holds the name and email, that would make it easier to work with the array and the list. This is somewhat simplified of course. – Joakim Danielson Apr 25 '22 at 09:21

1 Answers1

2

You want to handle multiple people but you have only one name and one email property.

You need an array. A swifty way is a custom struct

struct Person  {
    var name, email : String
}

In the view replace name and email with an empty array of Person

@State private var people = [Person]()

In the ForEach loop iterate over the indices and bind the text parameter to the person at given index.

I don't have your custom text fields, the code uses the default fields

ForEach(people.indices, id: \.self) { index in
    VStack {
        TextField("Enter name", text: $people[index].name)
        TextField("Enter email", text: $people[index].email)
    }
    .padding()
}

Finally in the button action add a new Person to people

Button {
    print("add person tapped")
    people.append(Person(name: "", email: ""))
vadian
  • 274,689
  • 30
  • 353
  • 361
  • from where the users came from? It is giving error: _could not find users_ in the last line `users.append(Person(name: "", email: ""))` – Taimoor Arif Apr 25 '22 at 09:59
  • My bad, replace `users` with `people` – vadian Apr 25 '22 at 10:00
  • this worked but one last thing, there is no textfield on load. When I tap on button, then it is adding the textfields, I want 1 textfield for name and 1 for email there on load too. – Taimoor Arif Apr 25 '22 at 10:18
  • Declare the data source with one default item `@State private var people = [Person(name: "", email: "")]`. The view shows one pair of text fields for each person in the array – vadian Apr 25 '22 at 10:34