I'm trying to format an expiry field so that it formats the text as follows: MM / YY I can get the textfield to add in the extra characters when the user is typing however when I come to delete the numbers the code will not allow you to go passed two characters before adding in the " / " again. Is there a way I can recognise when the user is deleting and bypass the text field check?
ExpiryOutlet.addTarget(self, action: #selector(ExpiryDidChange(_:)), for: .editingChanged)
func ExpiryDidChange(_ textField: UITextField) {
if textField == ExpiryOutlet {
if textField.text != "" && textField.text?.characters.count == 2 {
textField.text = "\(textField.text!) / "
}
}
}
Thanks
You can subclass UITextField and create a custom field to allow the user to input numbers only by adding a target to your object for controlEvents editingChanged with a selector to update UI.
First lets subclass UITextField:
We need also to properly format the field text by filtering all non digits characters converting them to Int using flatMap on the string representation of them and returning an array of Int ranging from 0 to 9. We need to place the slash character depending on the numbers of digits entered by the user by switching the number of digits in the string. Considering the fact that it is an expiration field you will need also to check if the month and year entered by the user still valid. So lets add month and year properties to ExpirationField to return their value. The same applies to the Date so we can compare it to the current month and year to validate the expiration date:
Then You just drag a text field to your view, select it and set custom class to ExpirationField in the inspector:
Sample
The problem is that you've implemented the wrong method. Implement the delegate method
textField(_:shouldChangeCharactersIn:replacementString:)
. This allows you distinguish where the text is changing (the second parameter is the range), and what the new text is — in the case of the backspace,replacementString
will be empty.