I am new to SwiftUI from UIKit and I have a question regarding the behavior of the TextField.
struct ContentView: View {
@State private var text = ""
@State private var words: [String] = []
var body: some View {
Form {
Section {
TextField("Input", text: $text) {
words.insert(text, at: 0)
text = ""
}
}
Section {
Button("Clear") {
text = ""
}
}
Section {
ForEach(words, id: \.self) { word in
Text(word)
}
}
}
}
}
The behavior I would like to do is to clear the text and add it to a list. After the input the text field will be cleared. The problem now is that text = ""
is called but it didn't clean up the field. However, by having a separate button below it works correctly.
For the context, I need to set the minimum deployment version to iOS14
and I am using Xcode 14.0.1
.
I have tried to move it to a function but didn't help either.
CodePudding user response:
in Clear Button before text = ""
just append in the array
struct ContentView: View {
@State private var text = ""
@State private var words: [String] = []
var body: some View {
Form {
Section {
TextField("Input", text: $text) {
words.insert(text, at: 0)
text = ""
}
}
Section {
Button("Clear") {
words.append(text) // <-- here append first and then clear.
text = ""
}
}
Section {
ForEach(words, id: \.self) { word in
Text(word)
}
}
}
}
}
CodePudding user response:
For iOS 14, you can achieve it by using UIViewRepresentable
of UITextField and Coordinator
class to manage textfield delegate.
Here is the working code for the same.
struct TextFieldView: View {
@State private var text = ""
@State private var words: [String] = []
var body: some View {
Form {
Section {
//Use here UIViewRepresentable class of TextField
CustomTextFieldView(inputText: $text, arrWords: $words, placeHolderText: "Input Text")
}
Section {
ForEach(words, id: \.self) { word in
Text(word)
}
}
}
}
}
struct CustomTextFieldView: UIViewRepresentable {
@Binding var inputText: String
@Binding var arrWords: [String]
var placeHolderText: String
func makeUIView(context: Context) -> UITextField {
let textView = UITextField()
textView.placeholder = placeHolderText
textView.delegate = context.coordinator
textView.autocapitalizationType = .sentences
return textView
}
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = inputText
}
func makeCoordinator() -> Coordinator {
Coordinator($inputText, textArr: $arrWords)
}
class Coordinator: NSObject, UITextFieldDelegate {
var text: Binding<String>
var arrText: Binding<[String]>
init(_ text: Binding<String>, textArr : Binding<[String]>) {
self.text = text
self.arrText = textArr
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
arrText.wrappedValue.append(textField.text!)
textField.text = ""
return true
}
}
}
In iOS 15 and above versions, you can manage it by using the onCommit
method of TextField
TextField("Input", text: $text).onSubmit {
words.insert(text, at: 0)
text = ""
}