Here’s my contribution, I think this one works pretty well. You can insert a negative at the start even with a number already in place. You can cut and paste. Good times. I’m new to Swift though, so please give tips and feedback if you have any.
Updated this to use numberFormatter, which we learn about in Chapter 7. This solution is much better, because it adapts to different number formatting based on the device region.
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
let currentLocale = Locale.current
let decimalSeparator = currentLocale.decimalSeparator ?? "."
print("Current text: \(String(describing: textField.text))")
print("Replacement text: \(string)")
print("Index: \(range.location)")
print("DecimalSeparator: \(decimalSeparator)")
// SECOND TRY AT BRONZE CHALLENGE, this one works great!
var checkValidString: String = textField.text!
checkValidString.insert(contentsOf: string.characters,
at: checkValidString.index(checkValidString.startIndex, offsetBy: range.location))
let checkValidNumber = numberFormatter.number(from: checkValidString)
if checkValidNumber == nil, string != "", checkValidString != decimalSeparator,
checkValidString != "-", checkValidString != "-\(decimalSeparator)" {
return false
} else {
return true
}
}
Without seeing the code, those two variable names (checkValidString and checkValidNumber) sound like function names. It is important that you use informative names to denote things in your code.
Good point, I suppose using a verb in the name implies a function. To get an idea of better naming conventions, what would you suggest instead for those variable names?