0

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)"
    }
}
Dani
  • 3,427
  • 3
  • 28
  • 54
  • Did it successfully stop you from entering any more text when it reaches 200 chars? – Sweeper Jul 06 '17 at 16:27
  • Are yo sure that your delegate methods are called by putting a break point? – Fangming Jul 06 '17 at 16:27
  • @Sweeper - it reaches the limit and it stops. @Fangming Ning - Yes, the delegate works. @rmaddy - It's not hidden, it's visible. I see the `UILabel` – Dani Jul 06 '17 at 17:05

1 Answers1

2

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.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I've added `descriptionTextView.addTarget(self, action: #selector(textChanged), for .editingChanged)` but it shows an error related to the 'for' saying "Expected expression in list of expressions" – Dani Jul 06 '17 at 16:57
  • @Dani You need an `:` after `for`. My bad! – Sweeper Jul 06 '17 at 16:58
  • I figured that was the case and I tried with `:` but it shows another error that states "Value of type TextViewX has no member add target" – Dani Jul 06 '17 at 17:02
  • @Dani I've found what's wrong with your code now. See the edited answer. – Sweeper Jul 06 '17 at 17:16
  • OMG! YES! hahaha one tiny `_` and the entire code is invalid! Thank you so much! – Dani Jul 06 '17 at 17:23