Post

Replies

Boosts

Views

Activity

Reply to In SwiftUI, any way to intercept each character entered in a TextField?
I know this is a few months old, but I've been looking at this too. (On a side note, I think it's abysmal that Apple didn't include a per character filter and a way to reject the value.) I ended up writing a floating point parser (simple state machine) to validate text. It returns true if the text is a valid starting part of the number and has a computed property that tells me it's a complete number of not. This is required because "-" is a valid beginning of a floating point number, so is ".", etc. Of course ".." is not so you have to have something to validate these strings. Because there is no per character event that I could find, I store the previous value (keep in mind that it can be shorter or longer - they user may enter a character and delete it). If the new value is not valid, I set the old value. The examples I've seen here, may not work when you have an observable object set as an environment variable. I ran into infinite loops - so I only assign the new value if it's different than the current. Here's my onReceive for the TextField. .onReceive(Just(data.text)) { newValue in /* Filter the new value */ let filtered = newValue.filter { Set(Self.allowedChars).contains($0) } /* If valid or empty, save the old value and set the new */ if (filtered.count == 0) || (validator.check(value: filtered)) { oldValue = data.text if self.data.text != filtered { self.data.text = filtered } } /* Otherwise, set the old value */ else { self.data.text = oldValue } } Validator checks the string to ensure it is part of, or a complete floating point number. Mine allows numbers like -0.355e-05. Now if I only knew what keyboard I was going to use. There doesn't appear to be a standard keyboard (except for the full one) that can be used for floating point.
Jun ’22