简体   繁体   中英

limit TextView to certain number of lines in swift 2

I need to restrict my textview to only 6 lines. How do I limit my textview to 6 lines? I have put some character limit of 50 characters anyways.

That is rarely simple to achieve. Try out following code

inputTextView.textContainer.maximumNumberOfLines = 6
inputTextView.textContainer.lineBreakMode = .ByWordWrapping

for swift 4 this one worked for without any bugs:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let existingLines = textView.text.components(separatedBy: CharacterSet.newlines)
    let newLines = text.components(separatedBy: CharacterSet.newlines)
    let linesAfterChange = existingLines.count + newLines.count - 1
    return linesAfterChange <= textView.textContainer.maximumNumberOfLines
}

and if you want to limit characters also:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let existingLines = textView.text.components(separatedBy: CharacterSet.newlines)
        let newLines = text.components(separatedBy: CharacterSet.newlines)
        let linesAfterChange = existingLines.count + newLines.count - 1
        if(text == "\n") {
            return linesAfterChange <= textView.textContainer.maximumNumberOfLines
        }

        let newText = (textView.text as NSString).replacingCharacters(in: range, with: text)
        let numberOfChars = newText.count
        return numberOfChars <= 30 // 30 characters limit
    }
}

don't forget to add how many lines you want the limit to be in viewDidLoad :

txtView.textContainer.maximumNumberOfLines = 2

Just in case, don't forget to guard range size before applying it to the string. Otherwise, you will get crash if the user will do this:

Type maximum length text Insert something (Nothing will be inserted due to length limitation, but iOS doesn't know about it) Undo insertion (You get crash, cause range will be greater than actual string size)

Also, using iOS 13 users can accidentally trigger this by gestures

I suggest you add to your project this

extension String {
    func replace(with text: String, in range: NSRange) -> String? {
        guard range.location + range.length <= self.count else { return nil }
        return (self as NSString).replacingCharacters(in: range, with: text)
    }
}

And use it like this:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    guard let newText = textView.text.replace(with: text, in: range) else { return false }
    return newText.count < maxNumberOfCharacters
}

Otherwise, you will constantly getting crashed in your app

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM