开发者

How to insert grouping comma in NSString as typed?

开发者 https://www.devze.com 2023-04-05 04:00 出处:网络
A user enters a numerical string in a UILabel and the text is displayed as the user types. NSString *input = [[sender titleLabel] text];

A user enters a numerical string in a UILabel and the text is displayed as the user types.

NSString *input = [[sender titleLabel] text];
[display_ setText:[[display_ text] stringByAppendingString:input]];

This works fine and I format the display using NSNumberFormatter so that if 1000000 is entered it is converted to 1,000,000 upon tapping another button.

However, I'd like to get those grouping commas to be displayed as the user types. I can understand how to insert things into strings, but how to do it as the user types is not clear to me. Would this require a mutable string?

Maybe somehow monitor the string length and split it into groups of three and make and display a new string with the commas inserted? I could probably do that, but it is the "as it is typed" part that has me stymied.

Another thought is to append and display the string, then read the display into a new NSString and format it and display it again right away. So I tried that, and it almost works:

 if (userIsEntering)    
{
NSNumberFormatter *fmtr = [[NSNumberFormatter alloc] init];
[fmtr setNumberStyle:NSNumberFormatterDecimalStyle];
[fmtr set开发者_如何转开发GroupingSeparator:@","];
[fmtr setDecimalSeparator:@"."];

NSString *out = [[display_ text] stringByAppendingString:digit];
NSNumber *num = [fmtr numberFromString:out];
NSString* formattedResult = [fmtr stringFromNumber:num];

[display_ setText: [NSString stringWithFormat:@"%@", formattedResult]];

[fmtr release];
}

And, along with the fact that the formatter is created and released with every digit entered, after 4 digits it returns null.

UPDATE: I figured out how to do it in a label (with some help from @Michael-Frederick). It uses an NSNotification.

This works perfectly for non-decimal numbers, but when I try to enter a decimal point it is ignored and removed. If I do not invoke this method, the decimal point is accepted and all works well.

Numeric entry is as follows (from a button):

NSString *digit = [[sender titleLabel] text];
if (userIsStillWorking_)        
{
[display_ setText:[[display_ text] stringByAppendingString:digit]];
    }
else
{
[display_ setText: digit];
userIsStillWorking_ = YES;
    }
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateDisplay" object:nil];

And the updateDisplay method called by the notification is:

{
NSString *unformattedValue = [display_.text stringByReplacingOccurrencesOfString:
          @"," withString:@""];
unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:
          @"." withString:@""];
NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:unformattedValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setGroupingSeparator:@","];
[formatter setDecimalSeparator:@"."];
[display_ setText: [ formatter stringFromNumber:amount]];
[formatter release];
}

I've tried commenting out

unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:
                   @"." withString:@""];

but that makes no difference.


EDIT: A user cannot type into a uilabel. You need to use either a uitextfield or a uitextview.

If you want to use a uitextfield, do something like this...

- (void) viewDidLoad {
[super viewDidLoad];
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}

- (void) textFieldDidChange:(UITextField *)textField {
    NSString *unformattedValue = [textField.text stringByReplacingOccurrencesOfString:@"," withString:@""];
    unformattedValue = [unformattedValue stringByReplacingOccurrencesOfString:@"." withString:@""];

    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [formatter setGroupingSeparator:@","];
    [formatter setDecimalSeparator:@"."];

    NSNumber *amount = [NSNumber numberWithInteger:[unformattedValue intValue]];
    textField.text = [formatter stringFromNumber:amount];

    [formatter release];
}

Note that you are correct that NSNumberFormatter should be declared outside of the textFieldDidChange method. Note that this code would actually be for an integer. You could have to switch intValue to floatValue if need be. This code is untested, it is more of a general guide.


The best way to do this is to use 2 UIlabels. 1 of the labels is used to feed your NSNumberFormatter object by using [NSString stringByAppendingString:digit]; The other label is actually displayed. The trick is to set the label that is unformatted to hidden and the other label is set as an output for the number formatter. By feeding the hidden label to the number formatter, and outputting the displayed label from the number formatter, the number formatter should be set to the NSDecimalNumber style. Setting it all up this way, the result displayed is automatic commas while typing.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号