Home > front end >  SwiftUI TextField cannot be cleaned in onCommit functions
SwiftUI TextField cannot be cleaned in onCommit functions

Time:11-01

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.

sample

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

enter image description here

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 = ""
}
  • Related