@State var multiOptions = [""]
I'm trying to create textfields for a user to populate with numbers but I want them to choose the amount of textfields they will populate. To do this I have a ForEach loop.
ForEach(multiOptions.indices, id: \.self) { index in
TextField("Enter your option...", text: $multiOptions[index])
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
}
This loop creates a textfield for every empty string in multiOptions. I will include a way for the user to specify the amount of textfields they want but I was wondering if there was a way to use the users number and multiply it to multiOptions so I have the amount of empty strings that the user would like. So if the user chooses to have 6 textfields then multiOptions will have 6 empty strings.
CodePudding user response:
Here is a relatively simple answer, that is very simple to implement:
struct VariableTextFields: View {
@State var fieldCount: Int = 1
@State var multiOptions = [""]
var body: some View {
VStack {
Button {
multiOptions.append("")
} label: {
Text("Add Field")
}
List {
ForEach(multiOptions.indices, id: \.self) { index in
TextField("Enter your option...", text: $multiOptions[index])
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.onDelete { offsets in
multiOptions.remove(atOffsets: offsets)
}
}
}
}
}
SwiftUI will keep track of the count of multiOptions
in the ForEach
, so all you need to do is allow the user to add and subtract from it. I implemented this behavior with a button and an .onDelete()
on a List
.
CodePudding user response:
Here is a possible approach for you:
struct ContentView: View {
@State private var options: [String] = [String]()
@State private var countOfOptions: Int = Int()
var body: some View {
VStack(spacing: 5.0) {
HStack {
TextField("Enter count of Options", text: Binding(get: { () -> String in return (countOfOptions != 0) ? String(describing: countOfOptions) : "" },
set: { newValue in countOfOptions = Int(newValue) ?? 0 }), onCommit: { optionBuilder() })
.textFieldStyle(RoundedBorderTextFieldStyle())
Button("Create Options") { optionBuilder() }
Button("removeAll") { options.removeAll(); countOfOptions = 0 }.foregroundColor(.red)
}
ForEach(options.indices, id: \.self) { index in
TextField("Enter your option...", text: Binding(get: { () -> String in return options[index] },
set: { newValue in options[index] = newValue }))
.textFieldStyle(RoundedBorderTextFieldStyle())
.transition(AnyTransition.asymmetric(insertion: AnyTransition.move(edge: Edge.trailing), removal: AnyTransition.move(edge: Edge.leading)))
}
}
.padding(.horizontal)
.animation(Animation.default, value: options)
}
private func optionBuilder() {
if options.count < countOfOptions {
for _ in 0..<countOfOptions {
if (options.count < countOfOptions) { options.append(String()) }
else { break }
}
}
else {
for _ in 0..<options.count {
if (options.count > countOfOptions) { options.removeLast() }
else { break }
}
}
}
}