Search code examples
iosswiftuitextviewuitextviewdelegate

UITextView limit characters and display count left


I'm trying limit the characters for a UITextView to 200. It gets the data from Firebase Database (if it's available), if not - the UILabel that represents the characters left should be hidden - hence, if there's data (text in the text field it should present the UILabel with left characters.

I've made sure to conform my UIViewController as a delegate of UITextViewDelegate and I've also set up IBOutlet weak var descriptionTextView: TextViewX! (TextViewX is a subclass of UITextView) and set the descriptionTextView.delegate = self in the viewDidLoad() method. Once you start typing in the text view, the label count is simply not updated or shown at all.

Also, I'd also would like to change the color of the UILabel from green to red when it detects that there are less than 30 characters left.

Here's the code that I have, but it's not working. The characters left is not shown at at all:

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

func textViewDidChange(textView: TextViewX)
{
    let currentCharacterCount = 200 - textView.text.characters.count

    if currentCharacterCount >= 30 {
        descriptionCharacterCountLabel.text = "\(200 - textView.text.characters.count)"
    }
    else
    {
        descriptionCharacterCountLabel.textColor = UIColor.red
        descriptionCharacterCountLabel.text = "\(200 - textView.text.characters.count)"
    }
}

Solution

  • If you look closely at the docs for UITextViewDelegate, you will see that textViewDidChange is defined like this:

    optional func textViewDidChange(_ textView: UITextView)
    

    Look at the parameter! It requires a parameter with an external parameter name of _!

    Look what you've written:

    func textViewDidChange(textView: TextViewX)
    

    Your parameter's external name is textView!

    This is why it does not work.

    So, just add _ and a space before textView and change the type of the parameter to UITextView.