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.)
10 Answers
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; } 15 Comments
rmaddy
This is correct but why is the variable named
numberOfLines when it is the number of characters?William Kinaan
yes this is correct, i forgot about the number of lines
rmaddy
@WilliamKinaan What number of lines? There's nothing in the question about limiting the number of lines.
Roberto
Shouldn't the last line be
return numberOfChars <= 10; (the less-than symbol should be less-than-or-equal-to)?Swany
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 } |
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
Lance Samaria
in Swift 4 its: let numberOfChars = newText.count
Yaroslav Dukal
@LanceSamaria thanks, updated my answer to Swift 4, since Swift 3 is no longer relative..
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
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
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
Torsten B
If pasting text is allowed, this will not work
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
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
Yaroslav Dukal
what's adjust frames for ?
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 }
UITextFieldwithmyMessageObjectLabelis it right? Now I got this error Use of undeclared type 'myMessageObjectLabel'. I'm using swift 1.2 at now, could be a problem?