2

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?

Jack
  • 16,677
  • 8
  • 47
  • 51
bhzag
  • 2,932
  • 7
  • 23
  • 39

3 Answers3

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
  • 3
    This 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