Lance Samaria Lance Samaria - 1 year ago 73
Swift Question

Swift iOS -How to test for only Return "\n" key character being entered inside a TextView

I have a textView that tests for white space using the delegates

fileprivate let whitespace = CharacterSet.whitespaces

func textViewDidChange(_ textView: UITextView) {
if textView.text!.trimmingCharacters(in: whitespace) == ""{
sendButton.isEnabled = false
}else{
sendButton.isEnabled = true
}
}

func textViewDidEndEditing(_ textView: UITextView) {
if textView.text!.trimmingCharacters(in: whitespace) == ""{
sendButton.isEnabled = false
sendButton.layer.backgroundColor = UIColor.lightGray.cgColor
}else{
sendButton.isEnabled = true
sendButton.layer.backgroundColor = UIColor.red.cgColor
}
}


If the user enters all spaces the the sendButton never becomes enabled. But if the user types in 1 or more return key characters "\n" it's still recognized as a character and the sendButton does become enabled.

In the textView delegates
shouldChangeTextInRange
,
textViewDidChange
, and
textViewDidEndEditing
I tried adding
textView.text! == "\n"
:

fileprivate let whitespace = CharacterSet.whitespaces

func textViewDidChange(_ textView: UITextView) {
if textView.text!.trimmingCharacters(in: whitespace) == "" || textView.text! == "\n"{
sendButton.isEnabled = false
}else{
sendButton.isEnabled = true
} }

func textViewDidEndEditing(_ textView: UITextView) {
if textView.text!.trimmingCharacters(in: whitespace) == "" || textView.text! == "\n"{
sendButton.isEnabled = false
}else{
sendButton.isEnabled = true
}
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if textView.text!.trimmingCharacters(in: whitespace) == "" || textView.text! == "\n"{
sendButton.isEnabled = false
}else{
sendButton.isEnabled = true
}
return true
}


The button still becomes enabled.

How do I get the same response as testing for whitespace only?

Answer Source

Think about what you're doing here:

    if textView.text!.trimmingCharacters(in: whitespace) == "" || textView.text! == "\n" {

Split that into pieces:

    // Part 1 - get the text from textView, and remove whitespace characters
    textView.text!.trimmingCharacters(in: whitespace)

    // Part 2 - get the text from textView
    textView.text!

    IF "Part 1" == ""
    OR
    IF "Part 2" == "\n"

So, what happens if textView contains 4 spaces and a carriage return?

Part 1 is not true, because stripping the spaces leaves you with "\n"

Part 2 is not true, because it is "(four spaces)\n"

That should explain why your current code is not getting what you expect.

However, as @rmaddy suggested, this should do it:

func textViewDidChange(_ textView: UITextView) {
    let str = textView.text.trimmingCharacters(in: .whitespacesAndNewlines)
    if str == "" {
        sendButton.isEnabled = false
    } else {
        sendButton.isEnabled = true
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download