0

I want the users see the $ and comma when they are typing in a textfield from numberPad (Without a decimal dot). Previously I got help and use below codes. But clients will not type the decimal (Only Int value).

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let oldText = textField.text! as NSString
    var newText = oldText.stringByReplacingCharactersInRange(range, withString: string) as NSString!
    var newTextString = String(newText)

    let digits = NSCharacterSet.decimalDigitCharacterSet()
    var digitText = ""
    for c in newTextString.unicodeScalars {
        if digits.longCharacterIsMember(c.value) {
            digitText.append(c)
        }
    }

    let formatter = NSNumberFormatter()
    //        formatter.usesSignificantDigits = false
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
    formatter.locale = NSLocale(localeIdentifier: "en_US")
    let numberFromField = (NSString(string: digitText).doubleValue) / 100

    newText = formatter.stringFromNumber(numberFromField)

    textField.text = String(newText)

    return false

}

When typing, it always starts from the second decimal unit, How to remove the ".00" via editing the code and let it start from the unit? I tried for a long time, thanks in advance.

user6702783
  • 223
  • 4
  • 14

1 Answers1

1

First, you got some bad advice. You should not be using shouldChangeCharactersInRange to change the characters in a text field. That's for checking if the characters typed are valid for the field. The only thing you should do in this method is return true if the user entered digits or delete, otherwise false. (Remember, the user may be using an external keyboard so just having the keypad up isn't good enough to stop non-digit entry.)

Instead you should be using an @IBAction connected to the field's EditingChanged event. Inside this method is where you should update the text.

@IBAction func editingChanged(sender: UITextField) {
    let digits = sender.text?.digitsOnly ?? "0"
    sender.text = "$\(digits).00" // If I understand what you want.
}

The below extension should be somewhere in your code base. It's generally useful so store it in a gist or something, you will likely need it in future projects.

extension String {
    var digitsOnly: String {
        return componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
    }
}

You have to make sure that the IBAction is attached to the EditingChanged event:

enter image description here

For Swift 4x

extension String {
        var digitsOnly: String {
            return components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")
        }
    }
truthsayer
  • 397
  • 2
  • 8
  • 22
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • I want when the user type "1234", in the textfield it will show "$1" -> "$12" -> "$123" -> "$1,234" – user6702783 Sep 12 '16 at 01:57
  • Ahh, then check out this q/a: http://stackoverflow.com/questions/11787759/how-to-properly-format-currency-on-ios Just replace the `"$\(digits).00"` above with `numberAsString` from the answer. – Daniel T. Sep 12 '16 at 02:01
  • Hi, I tried your solution, the problem is when I am editing, the comma will not add immediately. It could appear only when I finish the editing. But it is not I want. – user6702783 Sep 12 '16 at 02:47
  • Then you didn't connect the IBAction to the field's EditingChanged event. Look in your storyboard. – Daniel T. Sep 12 '16 at 11:07
  • It works and it's far easier to understand than your original code. That's why I like doing it this way. :-) – Daniel T. Sep 13 '16 at 00:21
  • Exactly, now I understand more via different actions. Cheers! – user6702783 Sep 13 '16 at 01:38
  • I updated the Extension extension String { var digitsOnly: String { return components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "") } } Unfortunately, I can't get the commas to work anymore. Did I change something incorrectly for Swift 3? – bradford gray May 30 '17 at 21:14