Allow Only Digits to Be Typed in a UITextField on iOS

It’s not uncommon to need to restrict UITextField to allow only digits to be typed in. This could be for credit card numbers, account numbers, payment amounts, etc. The easiest way to accomplish this in Swift is using the textField(_:shouldChangeCharactersIn:replacementString:) delegate method.

This method gets called every time the user types a character, just before the text field is updated with the new text. This allows you to manipulate the newly typed text or (in our case) prevent it. Returning true or false tells the text field whether or not it should be updated with the character that was typed.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // Restrict digits-only to specific UITextField(s)
    if textField == creditCardNumberTextField {
        let allowedCharacters = CharacterSet.decimalDigits
        let characterSet = CharacterSet(charactersIn: string)
        return allowedCharacters.isSuperset(of: characterSet)
    }
    
    return true
}

What this implementation does is take the built-in decimalDigits character set, and return whether the character that was typed (string) is within that set. To do that, we first have to create a character set of what was typed.

This also applies to pasted text. In that case, string will be what was pasted, and it will not be allowed in the text field if it contains anything other than digits.