Maximum Length UITextField

When I tried How to set the maximum number of characters that can be entered into a UITextField using fast? , I saw that if I use all 10 characters, I also cannot erase the character.

The only thing I can do is cancel the operation (delete all characters together).

Does anyone know how not to lock the keyboard (so that I cannot add other letters / characters / numbers, but I can use backspace)?

+105
max ios uitextfield swift character
Aug 09 '14 at 21:51
source share
14 answers

In Swift 5 and iOS 12, try the following implementation of the textField(_:shouldChangeCharactersIn:replacementString:) method textField(_:shouldChangeCharactersIn:replacementString:) which is part of the UITextFieldDelegate protocol:

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let textFieldText = textField.text, let rangeOfTextToReplace = Range(range, in: textFieldText) else { return false } let substringToReplace = textFieldText[rangeOfTextToReplace] let count = textFieldText.count - substringToReplace.count + string.count return count <= 10 } 
  • The most important part of this code is the conversion of range ( NSRange ) to rangeOfTextToReplace ( Range<String.Index> ). Check out this video tutorial to see why this conversion is important.
  • For this code to work correctly, you must also set the textField value smartInsertDeleteType to UITextSmartInsertDeleteType.no . This will prevent the possible insertion of (unwanted) extra space during the insert operation.



The full code example below shows how to implement textField(_:shouldChangeCharactersIn:replacementString:) in a UIViewController :

 import UIKit class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard override func viewDidLoad() { super.viewDidLoad() textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no textField.delegate = self } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let textFieldText = textField.text, let rangeOfTextToReplace = Range(range, in: textFieldText) else { return false } let substringToReplace = textFieldText[rangeOfTextToReplace] let count = textFieldText.count - substringToReplace.count + string.count return count <= 10 } } 
+265
Aug 10 '14 at 0:13
source share

I do it like this:

 func checkMaxLength(textField: UITextField!, maxLength: Int) { if (countElements(textField.text!) > maxLength) { textField.deleteBackward() } } 

The code works for me. But I work with a storyboard. In the Storyboard, I add an action for the text field in the view controller in edit edited .

+44
Oct. 15 '14 at 10:34
source share

Update for Swift 4

  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return true } let newLength = text.count + string.count - range.length return newLength <= 10 } 
+28
Nov 03 '17 at 9:31 on
source share

Add more details from @Martin answer

 // linked your button here @IBAction func mobileTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 10) } // linked your button here @IBAction func citizenTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 13) } func checkMaxLength(textField: UITextField!, maxLength: Int) { // swift 1.0 //if (count(textField.text!) > maxLength) { // textField.deleteBackward() //} // swift 2.0 if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } } 
+14
May 26 '15 at 6:18
source share

In Swift 4

10 characters limit the text box and allow you to delete (return)

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == userNameFTF{ let char = string.cString(using: String.Encoding.utf8) let isBackSpace = strcmp(char, "\\b") if isBackSpace == -92 { return true } return textField.text!.count <= 9 } return true } 
+10
Jan 27 '18 at 12:35
source share
 func checkMaxLength(textField: UITextField!, maxLength: Int) { if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } } 

slight change for iOS 9

+8
Sep 20 '15 at 5:34
source share

Swift 3

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let nsString = NSString(string: textField.text!) let newText = nsString.replacingCharacters(in: range, with: string) return newText.characters.count <= limitCount } 
+7
Mar 02 '17 at 5:38 on
source share

If you want to overwrite the last letter:

 let maxLength = 10 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if range.location > maxLength - 1 { textField.text?.removeLast() } return true } 
+5
Jan 17 '18 at 12:01
source share

I posted the solution using IBInspectable , so you can change the maximum length value both in the interface builder and programmatically. Check here

+4
May 2, '15 at 10:03
source share

Beware of the UITextField undo error mentioned in this post: Set the maximum length of the UITextField character

here's how you fix it quick

 if(range.length + range.location > count(textField.text)) { return false; } 
+1
May 16 '15 at 12:34
source share
 Here is my version of code. Hope it helps! func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { return false } if (count(textField.text) > 10 && range.length == 0) { self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter) return false } else { } return true } 
+1
Nov 03 '15 at 4:35
source share

I use this protocol / extension in one of my applications and it is a little readable. I love the way it recognizes backspaces and explicitly tells you when a character is a backspace.

Some things to consider:

1. In any case, this protocol extension should indicate a character restriction. This will usually be your ViewController, but you can implement the character constraint as a computed property and return something else, such as a character limit on one of your models.

2. You will need to call this method inside your text box shouldChangeCharactersInRange delegate method. Otherwise, you cannot block text input by returning false, etc.

3. You probably want to allow reverse characters. . So I added an extra function to detect backspaces. Your shouldChangeCharacters method can verify this and return true at an early stage so that you always allow backspaces.

 protocol TextEntryCharacterLimited{ var characterLimit:Int { get } } extension TextEntryCharacterLimited{ func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{ let startingLength = textField.text?.characters.count ?? 0 let lengthToAdd = string.characters.count let lengthToReplace = range.length let newLength = startingLength + lengthToAdd - lengthToReplace return newLength <= characterLimit } func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{ if range.length == 1 && string.characters.count == 0 { return true } return false } } 

If any of you are interested, I have a Github repository where I took some of these character behavior rules and put it on iOS. There, a protocol that you can implement to display the character limit on Twitter shows how much you went above the character limit.

CharacterLimited Framework on Github

+1
Sep 10 '16 at
source share

Since delegates are 1 to 1 ratios, and I can use it elsewhere for other reasons, I like to limit the length of the text field by adding this code to my installation:

  required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setup() } required override init(frame: CGRect) { super.init(frame: frame) setup() } func setup() { // your setup... setMaxLength() } let maxLength = 10 private func setMaxLength() { addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged) } @objc private func textfieldChanged(_ textField: UITextField) { guard let text = text else { return } let trimmed = text.characters.prefix(maxLength) self.text = String(trimmed) } 
+1
Oct 13 '17 at 1:18 on
source share

You need to check if the existing row plus input is greater than 10.

  func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { NSUInteger newLength = textField.text.length + string.length - range.length; return !(newLength > 10) } 
-3
Aug 09 '14 at 23:16
source share



All Articles