How can I get limit the user's TextField input to numbers in Swift?
-
4Are you using storyboards? If you are there is an option in the property inspector to only allow numeric characters – Chris Nov 30 '14 at 16:42
-
also useful http://stackoverflow.com/a/26337774/294884 – Fattie Sep 28 '15 at 00:38
5 Answers
You can use UITextFieldDelegate
’s shouldChangeCharactersInRange
method to limit the user's input to numbers:
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
// Create an `NSCharacterSet` set which includes everything *but* the digits
let inverseSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
// At every character in this "inverseSet" contained in the string,
// split the string up into components which exclude the characters
// in this inverse set
let components = string.componentsSeparatedByCharactersInSet(inverseSet)
// Rejoin these components
let filtered = components.joinWithSeparator("") // use join("", components) if you are using Swift 1.2
// If the original string is equal to the filtered string, i.e. if no
// inverse characters were present to be eliminated, the input is valid
// and the statement returns true; else it returns false
return string == filtered
}
Updated for Swift 3:
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
// Create an `NSCharacterSet` set which includes everything *but* the digits
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
// At every character in this "inverseSet" contained in the string,
// split the string up into components which exclude the characters
// in this inverse set
let components = string.components(separatedBy: inverseSet)
// Rejoin these components
let filtered = components.joined(separator: "") // use join("", components) if you are using Swift 1.2
// If the original string is equal to the filtered string, i.e. if no
// inverse characters were present to be eliminated, the input is valid
// and the statement returns true; else it returns false
return string == filtered
}

- 37,080
- 10
- 92
- 128
-
1`join("", components)` breaks in Swift 2.0, do `components.joinWithSeparator("")` instead. – Nagendra Rao Sep 17 '15 at 16:29
-
4pretty code. this is a model of how to write self-documenting code. and dat's the only code. – Fattie Sep 28 '15 at 00:36
-
1let components = string.components(separatedBy: inverseSet) // Rejoin these components let filtered = components.joined(separator: "") for Swift 3 – JAck Oct 17 '16 at 11:05
-
-
-
@user924 Thanks for the suggestion. I’ll specifically mention UITextFieldDelegate. – Lyndsey Scott Apr 15 '18 at 18:16
-
-
@LyndseyScott it's just would be easier for new iOS developers (I usually develop Android apps). p.s. checked your profile, you're awesome xD, A Girl, Former model, and now iOS developer:) – user924 Apr 15 '18 at 19:17
For anyone looking for a shorter answer, I've found this quite useful.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// remove non-numerics and compare with original string
return string == string.filter("0123456789".contains)
}
Works in XCode 10.1, Swift 4.2

- 166
- 1
- 4
1st you have to inherit the UITextViewDelegate class with you own class
class ViewController: UIViewController, UITextViewDelegate {
2nd add an IBOutlet
@IBOutlet weak var firstName: UITextField!
3rd you have to assure this object is using
override func viewDidLoad() {
super.viewDidLoad()
firstName.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == firstName {
let allowedCharacters = "1234567890"
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharacterSet = CharacterSet(charactersIn: string)
let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
let Range = range.length + range.location > (fnameTF.text?.count)!
if Range == false && alphabet == false {
return false
}
let NewLength = (fnameTF.text?.count)! + string.count - range.length
return NewLength <= 10
} else {
return false
}
}

- 2,215
- 19
- 27
-
Looks good? But what is this "fnameTF.text?.count" referring too? And is missing a final return? – user3069232 May 16 '19 at 17:17
-
1fnameTF is a textField and fnameTF.text?.count means we are counting textField characters. @user3069232 – Akbar Khan May 20 '19 at 10:34
-
In swift 4.1 and Xcode 10
Add UITextFieldDelegate to your class
class YourViewController: UIViewController, UITextFieldDelegate
Then write this code in your viewDidLoad()
yourTF.delegate = self
Write this textfield delegate function
//MARK - UITextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//For numers
if textField == yourTF {
let allowedCharacters = CharacterSet(charactersIn:"0123456789")//Here change this characters based on your requirement
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
return true
}

- 16,698
- 6
- 112
- 113
Well the iOS provides no such functionality where you can specify textfield to accept only numeric characters. The only way through would be, one of UITextFieldDelegate methods, which is as follows,
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
You need to implement the following method and intercept the entered character and either through the following regular expression
"^([0-9]+)?(\\.([0-9]{1,2})?)?$"
or
[NSCharacterSet decimalDigitCharacterSet]
you can find out whether the entered character is numeric and return YES if it matches the regular expression or character set else return NO.

- 4,270
- 2
- 20
- 24