Ios 如何将货币字符串值设置为UITextField,从而保留编码?

Ios 如何将货币字符串值设置为UITextField,从而保留编码?,ios,uitextfield,nsnumberformatter,Ios,Uitextfield,Nsnumberformatter,我正在开发一个应用程序,希望根据当前的语言环境处理不同的货币格式。使用NSNumberFormatter我可以正确地将数字翻译成字符串并返回,不会出现问题 但是,如果我将字符串值放入UITextField中,然后将其取回,我将无法将字符串转换回数字,而将取而代之的是nil值 下面是解释此问题的示例代码: NSNumberFormatter *nf = [Utils currencyFormatter]; NSNumber *n = [NSNumber numberWithInt:10000];

我正在开发一个应用程序,希望根据当前的语言环境处理不同的货币格式。使用
NSNumberFormatter
我可以正确地将数字翻译成字符串并返回,不会出现问题

但是,如果我将字符串值放入
UITextField
中,然后将其取回,我将无法将字符串转换回数字,而将取而代之的是
nil

下面是解释此问题的示例代码:

NSNumberFormatter *nf = [Utils currencyFormatter];
NSNumber *n = [NSNumber numberWithInt:10000];
NSString *s = [nf stringFromNumber:n];
NSLog(@"String value = %@", s);
UITextField *t = [[UITextField alloc] init];
// I put the string into the text field ...
t.text = s;

// ... and later I get the value back
s = t.text;
NSLog(@"Text field text = %@", s);
n = [nf numberFromString:s];
NSLog(@"Number value = %d", [n intValue]);
其中,
currencyFormatter
方法定义如下:

+ (NSNumberFormatter *)currencyFormatter
{
    static NSNumberFormatter *currencyFormatter;
    if (!currencyFormatter) {
        currencyFormatter  = [[NSNumberFormatter alloc] init];
        [currencyFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
        [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        [currencyFormatter setLocale:[NSLocale currentLocale]];
        if ([currencyFormatter generatesDecimalNumbers] || [[currencyFormatter roundingIncrement] floatValue] < 1) {
            [currencyFormatter setGeneratesDecimalNumbers:YES];
            [currencyFormatter setRoundingIncrement:[NSNumber numberWithFloat:0.01]];   
        }
    }

    return currencyFormatter;
}
奇怪的是,第一行中
1
之间的间距字符在控制台中通过一个空中圆点表示,而在第二行中该圆点消失。我相信这是一个与编码相关的问题

有人能帮我解决这个问题吗? 谢谢大家!

编辑

我将测试代码更改为:

NSNumberFormatter *nf = [Utils currencyFormatter];
NSNumber *n = [NSNumber numberWithInt:10000];
NSString *s = [nf stringFromNumber:n];
NSLog(@"String value = %@ (space code is %d)", s, [s characterAtIndex:1]);
UITextField *t = [[UITextField alloc] init];
t.text = s;
s = t.text;
NSLog(@"Text field text = %@ (space code is %d)", s, [s characterAtIndex:1]);
n = [nf numberFromString:s];
NSLog(@"Number value = %d", [n intValue]);
要发现这一点:

2012-03-29 02:29:43.402 myMutuo2[45993:fb03] String value = € 10.000,00 (space code is 160)
2012-03-29 02:29:43.405 myMutuo2[45993:fb03] Text field text = € 10.000,00 (space code is 32)
2012-03-29 02:29:43.409 myMutuo2[45993:fb03] Number value = 0

NSNumberFormatter
将该空间写为非中断空间(ASCII字符160),然后
UITextField
将该空间重新编码为简单空间(ASCII字符32)。这种行为是否有已知的解决方法?也许我可以用一个不间断的空间来代替这个空间,但是。。。它适用于所有地区吗

一种可能的解决方法:您可以尝试通过正则表达式模式仅解析数字值(和点号),并基于该数字创建货币值。如果您这样做,用户可能会更容易原谅,如果他键入了另一个货币符号或其他不应该存在的符号…

我只能通过自定义类扩展
UITextField
来解决这个问题。在这个新类中,我放置了一个新的
@属性
,类型为
NSString
,其中存储了文本字段的“计算”字符串值。此字符串永远不会被修改,并将保留文本字段内容的原始编码

当您需要再次处理文本字段的原始未触及内容时,您必须引用此新属性,而不是引用
text
属性


使用单独的字符串容器是避免这些奇怪的编码更改的唯一方法。

我在以前版本的代码中已经这样做了。但我会遇到奇怪的错误、异常和崩溃,可能是一些奇怪的区域设置。我真的很想使用
NSNumberFormatter
的魔力来摆脱所有对字符串的自定义处理,并在一个“受控”环境中工作,在这个环境中,我使用相同的格式化程序对象对字符串/数字进行编码和解码。。。用户在
UITextField
中输入的内容实际上是通过调用
NSNumberFormatter
stringFromNumber:
方法生成的,因此我始终知道文本字段包含的内容已正确格式化。不需要添加更多的逻辑来解释该值。您是否可以只保存用户输入的值以供以后使用?为什么需要重新转换textfield内容?因为“用户输入”值是通过委托类中的
textfield:shouldChangeCharactersRange:replacementString:
方法写入UITextField的。此方法将自动将用户插入的字符转换为货币格式的字符串。该字符串保存到文本字段的
text
属性中,用于显示目的,我稍后从这里获取该字符串…它不适用于您的货币区域设置。我检查了它,得到了和你说的相同的空值。请再次查看我编辑的答案。这可能对你有所帮助。
2012-03-29 02:29:43.402 myMutuo2[45993:fb03] String value = € 10.000,00 (space code is 160)
2012-03-29 02:29:43.405 myMutuo2[45993:fb03] Text field text = € 10.000,00 (space code is 32)
2012-03-29 02:29:43.409 myMutuo2[45993:fb03] Number value = 0