Filtering input characters for a numeric text field using logical operators
Let's start with the assignment

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


The variable name suggests a boolean condition, but the value
is an optional range. It would be clearer to make it a boolean value:

let existingTextHasDecimalSeparator = textField.text?.range(of: ".") != nil


and similarly 

let replacementTextHasDecimalSeparator = string.range(of: ".") != nil


The variable name isRangeInReplacementString is meaningless, this would
become

let existingTextHasLetters = string.rangeOfCharacter(from: .letters) != nil


and here .letters is inferred as CharacterSet.letters, so we don't
need an extra variable for that.

The variable name returnValueBool is also meaningless, that might
become

let isInvalidChange = (existingTextHasDecimalSeparator &amp;&amp; replacementTextHasDecimalSeparator)
    || existingTextHasLetters
return !isInvalidChange


Now some simplifications: if the existing text has no decimal separator
then there is no need to check the replacement text for a separator.
And if you already detected a duplicate separator then you don't have
to check for invalid characters (letters). In other words: short-circuit:

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

    if textField.text?.range(of: ".") != nil &amp;&amp; string.range(of: ".") != nil {
        return false
    }
    if string.rangeOfCharacter(from: .letters) != nil {
        return false
    }
    return true
}


But there are still two problems:


It is not possible to replace text containing the decimal separator
with new text also containing the decimal separator with copy/paste,
e.g. replace 1.2 by 3.4.
The decimal separator is locale dependent, it can be a period,
a comma (e.g. in Germany) and perhaps also other characters.


The first problem can be solved by computing the new string after
the replacement first, and then check if that is valid (only digits
and at most one decimal separator).

The second problem can be solved by using a NumberFormatter to check
if the text is a valid decimal number.

That would lead to the following implementation (which is essentially
a translation of the code in Big Nerd Ranch Bronze Challenge: Disallow Alphabetic Characters
to the current Swift 4):

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

    guard let text = textField.text else { return false }
    // Compute new text after replacement:
    let newText = text.replacingCharacters(in: Range(range, in: text)!, with: string)
    // Check for empty string:
    if newText.isEmpty || newText == "-" {
        return true
    }
    // Check for valid decimal number:
    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    return formatter.number(from: newText) != nil
}