I am trying to validate user input in a TextField by removing certain characters using a regular expression. Unfortunately, I am running into problems with the didSet method of the text
var calling itself recursively.
import SwiftUI
import Combine
class TextValidator: ObservableObject {
@Published var text = "" {
didSet {
print("didSet")
text = text.replacingOccurrences(
of: "\\W", with: "", options: .regularExpression
) // `\W` is an escape sequence that matches non-word characters.
}
}
}
struct ContentView: View {
@ObservedObject var textValidator = TextValidator()
var body: some View {
TextField("Type Here", text: $textValidator.text)
.padding(.horizontal, 20.0)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
On the swift docs (see the AudioChannel struct), Apple provides an example in which a property is re-assigned within its own didSet method and explicitly notes that this does not cause the didSet method to be called again. I did some testing in a playground and confirmed this behavior. However, things seem to work differently when I use an ObservableObject
and a Published
variable.
How do I prevent the didSet method from calling itself recursively?
I tried the examples in this post, but none of them worked. Apple may have changed things since then, so this post is NOT a duplicate of that one.
Also, setting the text back to oldValue
within the didSet
method upon encountering invalid characters would mean that if a user pastes text, then the entire text would be removed, as opposed to only the invalid characters being removed. So that option won't work.
The validation takes a string from the parameter word, which then checks if in TextField contains that word. If TextField is not empty and the word can be found in TextField , then the function will return true. Otherwise, it will return false.
Basic Swift Code for iOS Apps Follow the below steps. Step 2 − Open Main. storyboard add one textField, one button and one label one below other as shown in the figure. On click of the button we will check whether the text field is empty or not and show the result in label.
struct ContentView: View { @State private var name: String = "Tim" var body: some View { VStack(alignment: . leading) { TextField("Enter your name", text: $name) Text("Hello, \(name)!") } } } When that's run, you should be able to type into the text field and see a greeting appear directly below.
Try to validate what you want in the TextField
onRecive
method like this:
class TextValidator: ObservableObject {
@Published var text = ""
}
struct ContentView: View {
@ObservedObject var textValidator = TextValidator()
var body: some View {
TextField("Type Here", text: $textValidator.text)
.padding(.horizontal, 20.0)
.textFieldStyle(RoundedBorderTextFieldStyle())
.onReceive(Just(textValidator.text)) { newValue in
let value = newValue.replacingOccurrences(
of: "\\W", with: "", options: .regularExpression)
if value != newValue {
self.textValidator.text = value
}
print(newValue)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With