This solution prevents non-decimal character input while allowing the user to delete previously entered characters:
let validCharacters = CharacterSet(charactersIn: ".0123456789")
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let replacementTextIsBackspace = (string.characters.count == 0 ? true : false)
if replacementTextIsBackspace {
return true
} else if string.rangeOfCharacter(from: validCharacters) != nil {
let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
let replacementTextHasDecimalSeparator = string.range(of: ".")
if existingTextHasDecimalSeparator != nil,
replacementTextHasDecimalSeparator != nil {
return false
} else {
return true
}
} else {
return false
}
}