How do you limit the number of characters in a UITextField
to 10
, and if the user enters more than 10
, only record the first 10 characters?
Asked
Active
Viewed 5,773 times
2
3 Answers
5
This solution deals with a user pasting text or tapping delete key too.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let length = count(textField.text.utf16) + count(string.utf16) - range.length
return length <= 10
}

tugce
- 1,008
- 1
- 10
- 25
-
what is the ```count``` method? Currently using Swift 3. – Ivan May 03 '18 at 15:48
-
@Ivan I switched to React Native but this is probably what you are looking for: https://stackoverflow.com/a/24037756/4953199 – tugce May 03 '18 at 19:15
2
You can check the text before it gets displayed by implementing the UITextFieldDelegate
.
class ViewController: UIViewController, UITextFieldDelegate {
textField(textField: UITextField!,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String!) -> Bool {
var shouldChange = false
if countElements(textField.text) < 10 {
shouldChange = true
}
return shouldChange
}
}

artey
- 1,243
- 7
- 10
-
How can I implement this function so my 'UITextField' only will take 10 chars? – bhzag Jul 10 '14 at 21:22
-
3This answer is incorrect. It makes no attempt to deal with a user pasting text or tapping the delete key. – rmaddy Aug 09 '14 at 22:15
0
Slight modification to the answer from @tugce:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// You can check for other things besides length here as well.
return isValidLength(textField: textField, range: range, string: string)
}
private func isValidLength(textField: UITextField, range: NSRange, string: String) -> Bool {
let length = ((textField.text ?? "").utf16).count + (string.utf16).count - range.length
return length <= 10
}
This addresses the question @Ivan asked:
what is the count method? Currently using Swift 3.
It also helps check for other conditions without crowding one method too much. For example, could do something like this to check several conditions while keeping functions a little smaller:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return isValidKey(string: string) && isValidLength(textField: textField, range: range, string: string)
}
private func isDeleteKey(string: String) -> Bool {
if let character = string.cString(using: String.Encoding.utf8) {
let isBackSpace = strcmp(character, "\\b")
if (isBackSpace == -92) {
return true
}
}
return false
}
private func isNumericKey(string: String) -> Bool {
return string.rangeOfCharacter(from: NSCharacterSet.decimalDigits) != nil
}
private func isValidLength(textField: UITextField, range: NSRange, string: String) -> Bool {
let length = ((textField.text ?? "").utf16).count + (string.utf16).count - range.length
return length <= 10
}
private func isValidKey(string: String) -> Bool {
return isDeleteKey(string: string) || isNumericKey(string: string)
}
I'll also mention that to utilize textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
you'll need to conform to the UITextFieldDelegate
and set the delegate of the text field. e.g.:
class MyClass: UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
init() {
textField.delegate = self
}
}

TJ Olsen
- 323
- 2
- 15