views:

51

answers:

2

I've found the code below, which I'm trying to make work in the UITableView shouldChangeCharactersInRange event. Without the currency symbol it works fine.

When I try to add the currency symbol, it just allows me to enter one number. What it should do is this, say I enter 7536, it should appear in the following steps £0.07, £0.75, £7.53, £75.36 but instead it appears as £0.07, £0.05, £0.03, £0.06

Heres the code.

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string
{    BOOL res = TRUE;

    double currentValue = [textField.text doubleValue];
    double cents = round(currentValue * 100.0f);

    if ([string length]) {
        for (size_t i = 0; i < [string length]; i++) {
            unichar c = [string characterAtIndex:i];
            if (isnumber(c)) {
                cents *= 10;
                cents += c - '0'; 
            }            
        }
    } else {
        // back Space
        cents = floor(cents / 10);
    }

    // This line next works without the currency symbol
    //textField.text = [NSString stringWithFormat:@"%.2f", cents / 100.0f];

    NSMutableString *aString = [NSMutableString stringWithFormat:@"%@", strCurrencySymbol];    
    [aString appendFormat:@"%.2f", cents / 100.0f];
    textField.text = aString;

    res = NO;
return res;

}

A: 

[@"£1.23" doubleValue] is 0. You have to skip over a leading currency symbol if there is one, something like:

NSString * currentText = textField.text;
NSRange range = [currentText rangeOfString:strCurrencySymbol];
if (range.location == 0)
{
  currentText = [currentText substringFromIndex:range.length];
}
double currentValue = [currentText doubleValue];

In general, I'd advise against doing stuff like this:

  • It might not work with all input methods (and IIRC shouldChangeCharactersInRange: isn't called for autocompletions).
  • It doesn't seem user-friendly, unless you work at a cash register (where they have a "00" key because otherwise entering "$100.00" is a pain). I want to be able to enter "1" and mean $1.00
  • It's not localized.
tc.
I'm not sure I understand can you give me the full shouldChangeCharactersInRange function. I'm not going to enable auto completion. Also, I doubt $100.00 will be entered very often. I'm going to pass in different currency symbols and decimal places.
Jules
You need to strip the currency symbol before calling `-doubleValue` to get `currentValue`. My code does this. The rest of your code can follow.
tc.
The value at the start won't have a currency symbol, the whole point is that I want to add it and show it after each keypress. Sorry if that wasn't clear.
Jules
You add it to textField.text, so the next time you read from textField.text you need to remove it before parsing it as a double. ARGH.
tc.
A: 
    NSCharacterSet *currencySet = [NSCharacterSet characterSetWithCharactersInString:@"$€£¥"];
    NSMutableString *strSource = [NSMutableString stringWithString:textField.text];
    if (![strSource isEqualToString:@""]) {
        [strSource replaceCharactersInRange: [strSource rangeOfCharacterFromSet:currencySet]  withString:@""];
    }

    double currentValue = [strSource doubleValue];
    double cents = round(currentValue * 100.0f);

    if ([string length]) {
        for (size_t i = 0; i < [string length]; i++) {
            unichar c = [string characterAtIndex:i];
            if (isnumber(c)) {
                cents *= 10;
                cents += c - '0'; 
            }            
        }
    } else {
        // back Space
        cents = floor(cents / 10);
    }

    NSMutableString *aString = [NSMutableString stringWithFormat:@"%@", strCurrencySymbol];    // does not need to be released. Needs to be retained if you need to keep use it after the current function.
    switch (intDecimalPlaces) {
        case 0:
            [aString appendFormat:@"%.0f", cents / 100.0f];
            break;
        case 1:
            [aString appendFormat:@"%.1f", cents / 100.0f];
            break;
        case 2:
            [aString appendFormat:@"%.2f", cents / 100.0f];
            break;
        case 3:
            [aString appendFormat:@"%.3f", cents / 100.0f];             
            break;
        default:
            break;
    }

    textField.text = aString;

I forgot to remove the currency symbol at the start. Then you add it at the end without problem.

Jules