47

I'd like to set a maximum number of characters allowed to be typed both in a UITextView and a UITextField. This number will be then shown in a little label (for user's reference, Twitter Style.)

3
  • You are checking the current length of the text, not what the length is about to become. Commented Oct 4, 2015 at 16:12
  • stackoverflow.com/a/1773257/4475605 Commented Oct 4, 2015 at 16:35
  • went on the link I added that code in ViewDidLoad and replaced UITextField with myMessageObjectLabel is it right? Now I got this error Use of undeclared type 'myMessageObjectLabel'. I'm using swift 1.2 at now, could be a problem? Commented Oct 5, 2015 at 8:29

10 Answers 10

127

Update Swift 4.X

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let newText = (textView.text as NSString).replacingCharacters(in: range, with: text) let numberOfChars = newText.count return numberOfChars < 10 // 10 Limit Value } 

Try this out:

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { let newText = (textView.text as NSString).stringByReplacingCharactersInRange(range, withString: text) let numberOfChars = newText.characters.count // for Swift use count(newText) return numberOfChars < 10; } 
Sign up to request clarification or add additional context in comments.

15 Comments

This is correct but why is the variable named numberOfLines when it is the number of characters?
yes this is correct, i forgot about the number of lines
@WilliamKinaan What number of lines? There's nothing in the question about limiting the number of lines.
Shouldn't the last line be return numberOfChars <= 10; (the less-than symbol should be less-than-or-equal-to)?
If you want to allow the user to delete chars when they "are over the limit" (can happen if you lower the char limit and user is editing with old (longer text), add a guard...guard !text.isEmpty else { return true }
|
38

SWIFT 4

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let newText = (textView.text as NSString).replacingCharacters(in: range, with: text) return newText.count < 10 } 

2 Comments

in Swift 4 its: let numberOfChars = newText.count
@LanceSamaria thanks, updated my answer to Swift 4, since Swift 3 is no longer relative..
12

Swift 4:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let newText = (textView.text as NSString).replacingCharacters(in: range, with: text) return newText.count <= 70 } 

Comments

9

Try this out:-

 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { print("chars \(textView.text.characters.count) \( text)") if(textView.text.characters.count > 20 && range.length == 0) { print("Please summarize in 20 characters or less") return false; } return true; } 

Comments

8

Swift 3.0

Just override this UITextFieldDelegate function, set the desired characterLimit variable and you are good to go:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let characterLimit = 5 let newText = NSString(string: textField.text!).replacingCharacters(in: range, with: string) let numberOfChars = newText.characters.count return numberOfChars < characterLimit } 

Comments

6

Update for Swift 5

Gives the most forward result

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { return range.location < 140 // limit to 140 chars } 

1 Comment

If pasting text is allowed, this will not work
3

Swift 4/ Xcode 9.1

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let currentText = textView.text ?? "" guard let stringRange = Range(range, in: currentText) else { return false } let changedText = currentText.replacingCharacters(in: stringRange, with: text) return changedText.count <= 399 // Pass your character count here } 

Comments

3

Swift 4 , Xcode 9.1 GM

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { return textView.text.count + (text.count - range.length) <= 200 } 

1 Comment

what's adjust frames for ?
3

Adding support of pasting text with cutting it by a maxLength + avoiding UNDO action crash:

 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if let maxLength = maxLength { let maxReplacementLength = min(range.length, maxLength - range.location) let replacementRange = NSRange(location: range.location, length: maxReplacementLength) let result = NSString(string: (textView.text ?? "")).replacingCharacters(in: replacementRange, with: text) if result.count <= maxLength && range.length <= maxLength - range.location { return true } textView.text = String(result[..<result.index(result.startIndex, offsetBy: min(result.count, maxLength))]) return false } return true } 

Comments

2

Swift 5

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { var newText = textView.text! newText.removeAll { (character) -> Bool in return character == " " || character == "\n" } return (newText.count + text.count) <= 40 } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.