Big Nerd Ranch Bronze Challenge: Disallow Alphabetic Characters
Two problems in your code

You check if the replacement string contains at least one allowed
character, so that pasting  "1A" into the text field would be accepted.
Instead you should check if the string contains no invalid character:

if string.rangeOfCharacterFromSet(
    NSCharacterSet(charactersInString: "-0123456789.").invertedSet) != nil {
    return false
}


(I prefer a comparison != nil over an optional binding to the
unused variable _ in this situation.) Note that this makes the initial
check for a non-empty string obsolete.

In order to prevent two decimal separators (such as "1.2.3"), you check if both
the existing string and the replacement string contain a period. But 
this prevents the replacement of – for example – "1.2" by "3.4" with
copy/paste. To handle that correctly, you have to build the
new string and check that:

if let existingString = textField.text as NSString? {
    let newString = existingString.stringByReplacingCharactersInRange(range, withString: string)
    // check if `newString` contains more than one dot `.`
    // ...
}


Possible improvements

The decimal separator is not always the
dot character ".". In Germany for example (and many other countries),
floating point numbers are written as "12,34" with a comma as separator, and that would be denied with your code.

You could determine the correct localized decimal separator at
runtime:

let separator = NSNumberFormatter().decimalSeparator


and use that instead of the hard-coded period. But that still does not
cover all invalid input, such as "12-34-56".

There is a better (and simpler) solution: Check if the new string
after replacement can successfully be converted to a number, using
a NSNumberFormatter. That will recognize valid numbers according to
the user's locale correctly:

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

    // Get current string as `NSString`
    guard let existingString = textField.text as NSString? else { return false }
    // Perform replacement:
    let newString = existingString.stringByReplacingCharactersInRange(range, withString: string)
    // Check for empty result ...
    if newString.isEmpty {
        return true
    }
    // ... or valid number:
    let fmt = NSNumberFormatter()
    fmt.numberStyle = .DecimalStyle
    return fmt.numberFromString(newString) != nil
}


Since creating a number formatter is "expensive" (compare
NSFormatter - NSHipster), you
can improve that further by creating the formatter only once – for example as a static property.