Reputation: 537
I created an UITextField
which allows users to input the only number, then auto adds 3 zeros at the last of the number string (with dot separator but now it's only showing as a comma instead of dot). For example if I input 3
the string in the text field will be 3.000
and limit at 12 characters input.
But now I have a problem is I can only input one number at the time and when I input another number it replace the old number I inputted. For example, I typed 3
in the text field it becomes 3.000
, then type 2
it becomes 2.000
instead of 32.000
. Below is my code to handle the typing:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
self.textField?.text = textField.text
let strTextOld = textField.text ?? ""
let numStringOld = strTextOld.replacingOccurrences(of: ".", with: "", options: String.CompareOptions.literal, range: nil)
var newValue: String = ""
if let digit = Int(string) {
let doubleItem = Int(numStringOld) ?? 0
let itemNew = ((doubleItem/1000) * 10) + (Int(string) ?? 0)
newValue = "\(itemNew * 1000)"
}
if string == "" {
let doubleItem = Int(numStringOld) ?? 0
let itemNew = Int((doubleItem / 1000) / 10)
newValue = "\(itemNew * 1000)"
}
guard let text: String = textField.text else {return true}
if newValue.length <= 12 {
return self.formatPrice(textFormat: newValue, labelFormat: textField)
}
return true
}
//format price for textfield
func formatPrice(textFormat: String, labelFormat: UITextField) -> Bool {
let formatStyle = NumberFormatter()
formatStyle.numberStyle = .decimal
let number = Double(textFormat.replaceMatches(regexp: "[^0-9]", with: ""))
if let number:NSNumber = NSNumber(value: number ?? 0) {
var strValue:String = formatStyle.string(from: number) ?? ""
formatStyle.decimalSeparator = "."
_ = strValue.replacingOccurrences(of: ",", with: ".")
if number == 0 {
strValue = ""
}
if labelFormat === self.textField {
self.textField?.text = "\(strValue)"
}
return true
}
return true
}
Upvotes: 0
Views: 642
Reputation: 166
I Added documentation for you to understand each step:
let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.currencySymbol = ""
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 0
return formatter
}()
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let suffix = ".000"
// using NSString will allow us to replase replacing characters in range and get the newString
guard let nsString = textField.text?.replacingOccurrences(of: suffix, with: "") as NSString? else { return false }
// The newString that will be achieved after this function returns
var newString = nsString.replacingCharacters(in: NSRange(location: (range.location - suffix.count) < 0 ? 0 : range.location - suffix.count, length: range.length > nsString.length ? nsString.length : range.length), with: string)
// Going to delete a character.
if string.isEmpty {
// The reason we have an extra "0" is because after we return "true" the last digit will be deleted.
textField.text = !newString.isEmpty ? "\(addCommas(to: newString.replacingOccurrences(of: ",", with: "")))\(suffix)0" : " "
return true
} else if newString.count <= 15 { // Going to add a character.
newString = "\(addCommas(to: newString.replacingOccurrences(of: ",", with: "")))\(suffix)"
textField.text = newString
}
return false
}
func addCommas(to string: String) -> String {
guard let newNumber = Float(string) else { return string }
return formatter.string(from: NSNumber(value: newNumber)) ?? string
}
Upvotes: 2