I have a converter which converts numbers. When user is typing a number from NumberPad keyboard into my cell textField I want it to be formatted and displayed in real time like:
1000 -> 1 000
10000 -> 10 000
1000000 -> 1 000 000
1000,77 -> 1 000,77
I know it should happen in textFieldDidChangeSelection method. Here is mine:
func textFieldDidChangeSelection(_ textField: UITextField) {
numberFromTextField = Double(textField.text!)
//This is for reload visible Rows in my tableView. Might not needed in my question's context.
let activeTextFieldIndexPath = IndexPath(row: textField.tag, section: 0)
var visibleIndexPaths = [IndexPath]()
for indexPath in tableView.indexPathsForVisibleRows! {
if indexPath != activeTextFieldIndexPath {
visibleIndexPaths.append(indexPath)
}
}
tableView.reloadRows(at: visibleIndexPaths, with: .none)
}
There I have a global variable numberFromTextField
which I made because I need to use the Double version of textField.text in my separate calculation methods.
How can I implement above formatted behaviour and at the same time save numberFromTextField = Double(textField.text!)
as I need it in my different calculations?
logic is following:
// --------------------- shouldChangeCharactersIn ------------------------------------------------
// Description: testField is formatted with correct separators if number
// Parameters
// textField : UITextField testField only
// shouldChangeCharactersIn range: NSRange
// replacementString string : String The last inserted String
// -------------------------------------------------------------------------------------------------
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "en_US") // Adapt to your case
formatter.usesGroupingSeparator = true
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.maximumFractionDigits = 6
formatter.decimalSeparator = "." // Adapt to your case
formatter.groupingSeparator = "," // Adapt to your case
// The complete string if string were added at the end
// Here we only insert figures at the end
// Let us first remove extra groupingSeparator we may have introduced to find the number
let completeString = textField.text!.replacingOccurrences(of: formatter.groupingSeparator, with: "") + string
var backSpace = false
if let char = string.cString(using: String.Encoding.utf8) {
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
backSpace = true
}
}
if string == "" && backSpace { // backspace inserts nothing, but we need to accept it.
return true
}
if string == "-" && textField.text! == "" { // Accept leading minus
return true
}
guard let value = Double(completeString) else { return false } // No double ; We do not insert
let formattedNumber = formatter.string(from: NSNumber(value: value)) ?? ""
textField.text = formattedNumber // We update the textField, adding typed character
return string == formatter.decimalSeparator // No need to insert the typed char: we've done just above, unless we just typed separator
}