1

In my current application, I have created a custom input container for the users to enter comments. Please refer to the picture below.

enter image description here

The textfield is set as the delegate for UITextFieldDelegate, and I would like to work with shouldChangeCharactersInRange such that if the textField is empty, the sendButton is a gray color, and when there is at least 1 character filled in, it changes to blue. However, currently with my code, the sendButton is blue to begin with, turns gray when 1 character is entered, and then back to blue when characters are greater than 1. Kinda weird, trying to figure out why that is. Here is my current relevant code:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if (textField.text?.characters.count)! > 0 {
        sendButton.setTitleColor(ovencloudBlueText, for: .normal)
    } else {
        sendButton.setTitleColor(newLoginGrayText, for: .normal)
    }
    return true
}

I know it's probably something simple that I'm missing. If this is a possible repeat, please let me know and I'll delete this post after checking out the reference link. Much thanks for your input.

iMoment
  • 243
  • 1
  • 4
  • 14

1 Answers1

3

It happens because shouldChangeCharactersIn triggered before updating the ui. So it begins with blue 'cause textfield is empty. And when you enter first character, shouldChangeCharactersIn works but if you check the textField.text?.characters.countat the moment, you will see it is 0 and sendButton.setTitleColor(newLoginGrayText, for: .normal) works. When you enter second character, textField.text?.characters.count comes 1 and it turns blue. You can do what you want like;

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let  char = string.cString(using: String.Encoding.utf8)!
        let isBackSpace = strcmp(char, "\\b")

        if (isBackSpace == -92) {
            print("Backspace was pressed")
        }

        if (textField.text?.characters.count)! == 0 {
          sendButton.setTitleColor(ovencloudBlueText, for: .normal)
        }
        else if (textField.text?.characters.count)! == 1 && isBackSpace == -92 {
          sendButton.setTitleColor(newLoginGrayText, for: .normal)
        }

    return true
}

You will see it works

AtaerCaner
  • 691
  • 7
  • 12
  • That's very interesting. I wasn't aware of the flow of events related to the UI. I have tried your code with a small modification on setting the button color to gray, and it does indeed work. It's not obvious to me right away why (textField.text?.characters.count)! == 0 would allow for my desired effect of the button turning blue, but I'll look at it more deeply in the coming hours. Much thanks for your help, and I hope this helps others as well! – iMoment Mar 13 '17 at 04:09
  • Yeah, a similar case happened to me once. `shouldChangeCharactersIn` does not work the way i expect. `(textField.text?.characters.count)! == 0` works for blue because `textField.text?.characters.count` is zero only when first character entered. In all other cases it's different from 0. You are welcome by the way :) If you change your question's title like "shouldChangeCharactersIn is triggered strangely", question will reach more people i think :) – AtaerCaner Mar 13 '17 at 17:17