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.