My Simple Bronze Solution, feedback welcome!

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

    let existingTextHasDecimalSeperator = textField.text?.range(of: ".")
    let replacementTextHasDecimalSeperator = string.range(of: ".")
    
    if string.rangeOfCharacter(from: .letters) != nil {
        return false
    }
    
    if existingTextHasDecimalSeperator != nil, replacementTextHasDecimalSeperator != nil {
        return false
    } else {
        return true
    }
}

I couldn’t figure out how to check the user of alphabetic characters, so I used your solution for this. I only changed the code so it follows the same pattern as the check for more than 1 decimal separator:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    let textHasAlphabeticCharacters = string.rangeOfCharacter(from: .letters)
    let existingTextHasDecimalSeperator = textField.text?.range(of: ".")
    let replacementTextHasDecimalSeperator = string.range(of: ".")
    
    if textHasAlphabeticCharacters != nil {
        return false
    } else if existingTextHasDecimalSeperator != nil, replacementTextHasDecimalSeperator != nil {
        return false
    } else {
        return true
    }
}