Why does my replacementTextHasLetter constant not prevent me from pasting in a letter into my textfield with the below conditional?

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

    let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
    let replacementTextHasDecimalSeparator = string.range(of: ".")

    let charactersNotAllowed = NSCharacterSet.letters
    let replacementTextHasLetter = string.rangeOfCharacter(from: charactersNotAllowed)

    if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil && replacementTextHasLetter != nil {

        return false

    }

    return true

}

But when it has its own separate conditional it works?

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

    let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
    let replacementTextHasDecimalSeparator = string.range(of: ".")

    let charactersNotAllowed = NSCharacterSet.letters
    let replacementTextHasLetter = string.rangeOfCharacter(from: charactersNotAllowed)

    if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil {

        return false

    }

    if replacementTextHasLetter != nil {

        return false

    }

    return true

}

EDIT: I figured it out. It's impossible for the first example to work since existingTextHasDecimalSeparator & replacementTextHasDecimalSeparator are basically determining if there is a decimal in the textfield and if the user is trying to enter a new one, to return false. When I add

&& replacementTextHasLetter != nil

to the conditional, it is just not really serving a purpose since all of the statements can't be true at the same time. Thank you @sonofabeach

1

There are 1 answers

0
rmaddy On BEST ANSWER

These two lines:

if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil {
    return false
}

if replacementTextHasLetter != nil {
    return false
}

Are the effectively the same as:

if (existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil) || replacementTextHasLetter != nil {
    return false
}

Note the use of || instead of && for the last condition.