How to Dynamically Format a Number to Have Commas in a Uitextfield Entry

How do you dynamically format a number to have commas in a UITextField entry?

Instead of inserting the commas on your own in shouldChangeCharactersInRange:, you can use an NSNumberFormatterDecimalStyle to handle the comma formatting for you. Even though it's called "decimal" style, it also inserts commas to appropriately group numbers into their thousands digits.

Note: To simplify matters, I'll assume you only want the text field to accept numeric entries and I'll also add logic to limit the user's input to numbers.

Edit: I've updated the code to handle decimals also as per the OP's request.

To utilize NSNumberFormatterDecimalStyle's formatting upon every character entry, try adding this to your shouldChangeCharactersInRange: delegate method:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

if (([string isEqualToString:@"0"] || [string isEqualToString:@""]) && [textField.text rangeOfString:@"."].location < range.location) {
return YES;
}

// First check whether the replacement string's numeric...
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
bool isNumeric = [string isEqualToString:filtered];

// Then if the replacement string's numeric, or if it's
// a backspace, or if it's a decimal point and the text
// field doesn't already contain a decimal point,
// reformat the new complete number using
// NSNumberFormatterDecimalStyle
if (isNumeric ||
[string isEqualToString:@""] ||
([string isEqualToString:@"."] &&
[textField.text rangeOfString:@"."].location == NSNotFound)) {

// Create the decimal style formatter
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:10];

// Combine the new text with the old; then remove any
// commas from the textField before formatting
NSString *combinedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *numberWithoutCommas = [combinedText stringByReplacingOccurrencesOfString:@"," withString:@""];
NSNumber *number = [formatter numberFromString:numberWithoutCommas];

NSString *formattedString = [formatter stringFromNumber:number];

// If the last entry was a decimal or a zero after a decimal,
// re-add it here because the formatter will naturally remove
// it.
if ([string isEqualToString:@"."] &&
range.location == textField.text.length) {
formattedString = [formattedString stringByAppendingString:@"."];
}

textField.text = formattedString;

}

// Return no, because either the replacement string is not
// valid or it is and the textfield has already been updated
// accordingly
return NO;
}

Swift: Add comma and $ in the textfield when typing

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:

Sample Image

For Swift 4x

extension String {
var digitsOnly: String {
return components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")
}
}

How to input currency format on a text field (from right to left) using Swift?

For Swift 3. Input currency format on a text field (from right to left)

override func viewDidLoad() {
super.viewDidLoad()

textField.addTarget(self, action: #selector(myTextFieldDidChange), for: .editingChanged)
}

@objc func myTextFieldDidChange(_ textField: UITextField) {

if let amountString = textField.text?.currencyInputFormatting() {
textField.text = amountString
}
}

extension String {

// formatting text for currency textField
func currencyInputFormatting() -> String {

var number: NSNumber!
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = "$"
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

var amountWithPrefix = self

// remove from String: "$", ".", ","
let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.count), withTemplate: "")

let double = (amountWithPrefix as NSString).doubleValue
number = NSNumber(value: (double / 100))

// if first number is 0 or all numbers were deleted
guard number != 0 as NSNumber else {
return ""
}

return formatter.string(from: number)!
}
}

UITextField format in xx-xx-xxx

Try below it will work

Objective-C

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int groupingSize = 2;
if([string length] == 0) {
groupingSize = 4;
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init] ;
NSString *separator = @"-";
[formatter setGroupingSeparator:separator];
[formatter setGroupingSize:groupingSize];
[formatter setUsesGroupingSeparator:YES];
[formatter setSecondaryGroupingSize:2];
if (![string isEqual: @""] && (textField.text != nil && textField.text.length > 0)) {
NSString *num = textField.text;
num = [num stringByReplacingOccurrencesOfString:separator withString:@""];
NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[num doubleValue]]];
textField.text = str;
}
return YES;
}

Swift-3

extension ViewController: UITextFieldDelegate {

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var groupSize = 2
let separator = "-"
if string.characters.count == 0 {
groupSize = 4
}
let formatter = NumberFormatter()
formatter.groupingSeparator = separator
formatter.groupingSize = groupSize
formatter.usesGroupingSeparator = true
formatter.secondaryGroupingSize = 2
if var number = textField.text, string != "" {
number = number.replacingOccurrences(of: separator, with: "")
if let doubleVal = Double(number) {
let requiredString = formatter.string(from: NSNumber.init(value: doubleVal))
textField.text = requiredString
}

}
return true
}
}

Auto suggest in UITextfield with comma separation

You can do it like this,

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{

if (textField.tag == tagTextFieldTag) //The text field where user types
{
textField.autocorrectionType = UITextAutocorrectionTypeNo;
autocompleteTableView.hidden = NO; //The table which displays the autosuggest
NSArray *autoComplete = [textField.text componentsSeparatedByString:@","];
NSString *substring = [NSString stringWithString:[autoComplete lastObject]];
if ([substring isEqualToString:@""])
{
autocompleteTableView.hidden = YES; //hide the autosuggest table if textfield is empty
}
[self searchAutocompleteEntriesWithSubstring:substring];

}

return YES;
}

this method works like,

  • componentsSeparatedByString seperates the textFields text by , and give it as an NSArray
  • lastObject takes the last object from that array. If it is @"" no searching otherwise searches for an matching element.

Hope this will help you.



Related Topics



Leave a reply



Submit