Reputation: 707
Is there something like textFieldDidChange available in Xcode 12 that will run on iOS versions earlier than 13?
I am using this function to read the contents of a UITextField whenever it changes:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
return false
}
let s: String = textField.text ?? ""
print("s = \(s)")
return true
}
but the printed output is always one character behind.
For example:
When I type in 1 the printed output is s = "
. Adding a 2 (the textfield now displays 12) prints s = 1
. After a 3 (textfield now contains 123), s = 12
. And so on. Always one character behind.
Why is this? (I'm guessing because the character does not become part of the textfield.text until the function returns true.)
This gets the contents:
func textFieldDidChangeSelection(_ textField: UITextField) {
let s: String = textField.text ?? ""
print("s = \(s)")
}
but it only works with iOS 13.x.
How do I get the contents of a UITextfield whenever it changes for any iOS version?
Upvotes: 0
Views: 1446
Reputation: 17844
Why is this? (I'm guessing because the character does not become part of the textfield.text until the function returns true.)
Correct, that's also why that method has a "should" in its name - you can veto that change by returning false
.
Use code like this
guard let text = textField.text as NSString? else {
return false
}
let newText = text.replacingCharacters(in: range, with: string)
to get a "preview" of what the content of the field would be if you in fact allow the change to happen by returning true
Upvotes: 1
Reputation: 31
yeah that's correct the character does not become the part of textfied.text until you return true that function
if you want to get all of character in textfield shouldChangeCharacters try this one
let oldText = textField.text!
let r = Range(range, in: oldText)
let text = oldText.replacingCharacters(in: r, with: string)
Upvotes: 1
Reputation: 77433
If you added a UITextField
in Storyboard, you can add an @IBAction
for the Editing Changed
event:
@IBAction func textFieldChanged(_ sender: Any) {
guard let tf = sender as? UITextField else { return }
let s: String = tf.text ?? ""
print("s = \(s)")
}
If you want to add it via code, add the action - you'll likely do this in viewDidLoad()
:
myTextField.addTarget(self, action: #selector(self.myTextFieldChanged(_:)), for: .editingChanged)
and add this func to your controller:
@objc func myTextFieldChanged(_ sender: Any) {
guard let tf = sender as? UITextField else { return }
let s: String = tf.text ?? ""
print("s = \(s)")
}
Upvotes: 0