I want to build a MacOS form that allows for the end user to add textfields in the same way one can add rows to an excel table. The reason I want to use textfields is because I can't seem to find an example of a Table that will allow me to add text.
I managed to get a basic setup using 'ForEach' and a button to append, however, when running the app from Xcode I am getting an error:
"the ID occurs multiple times within the collection, this will give undefined results!"
I realise that setting up unique ID's for each field is necessary, but I don't know how to set this up where the number of textfields that the end user will add can vary per form, and they are based on the append action. I even considered using the new 'GridRow' but it is only available for MacOS13 and above, and until Apple roles out with Ventura in late October I cannot implement this in the app. (no I do not want to run Ventura Beta as the machine this app will run on will only update MacOS when it officially roles out)
Here is my code:
import SwiftUI
struct ContentView: View {
@State private var name: [String] = []
@State private var address: [String] = []
@State private var telephoneNumber: [String] = []
var body: some View {
HStack {
VStack{
ForEach($name, id: \.self) {$name in TextField("Name", text:$name)
}
Button(action: {
name.append("")
}) {
Text("Add Name")
Image(systemName: "plus.circle.fill")
.foregroundColor(Color(.systemGreen))
}
}
.padding()
VStack {
ForEach($address, id: \.self) {$address in TextField("Address", text:$address)
}
Button(action: {
address.append("")
}) {
Text("Add Address")
Image(systemName: "plus.circle.fill")
.foregroundColor(Color(.systemGreen))
}
}
.padding()
VStack {
ForEach($telephoneNumber, id: \.self) {$telephoneNumber in
TextField("Telephone Number", text: $telephoneNumber)
}
Button(action: {
telephoneNumber.append("")
}) {
Text("Add Telephone Number")
Image(systemName: "plus.circle.fill")
.foregroundColor(Color(.systemGreen))
}
}
.padding()
}
Spacer()
.frame(width: 600, height: 600)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
What is more is that when I type in one of the textfields, take 'name' textfield as an example, the additional 'name' textfields below are populated with the same text, and the textfield loses its focus after one letter is typed.
Please will someone give me some guidance on how to correct this such that all additional textfields created are given a unique ID and save to the Form.
I worked it out: was an issue with the button action. See full code below:
import SwiftUI
struct ContentView: View {
@State private var persons: [Person] = []
var body: some View {
VStack{
ForEach($persons) { $person in TextField("Name", text: $person.name) }
Button(action: {
persons.append(Person.init(name: ""))
}) {
Text("Add Name")
Image(systemName: "plus.circle.fill")
.foregroundColor(Color(.systemGreen))
}
.padding()
}
Spacer()
.frame(width: 600, height: 600)
}
}
struct Person: Identifiable {
var id = UUID()
var name: String
}
Thanks again!