【发布时间】:2011-09-27 00:51:24
【问题描述】:
iPhone/Objective-C/Cocoa 新手在这里。根据 stackoverflow 上的一些帖子,我拼凑了一个 IBAction,我在我正在构建的基本 iPhone 计算器应用程序中使用它。 IBAction 与数字键盘配合使用,无需输入小数点即可输入十进制数字。
我非常努力地坚持“在处理货币时使用 NSDecimal”的格言,尽管我发现像许多其他发布问题的人一样很难做到这一点。我正在稳步前进,但是在我了解 NSDecimal 和 Format Specifications 之后,我确信这会看起来微不足道。
这是我正在使用的 IBAction(它由 Editing Changed UITextField 事件触发):
// called when user touches a key or button
- (IBAction)processKeystrokes:(id)sender
{
static BOOL toggle = YES; // was this method triggered by the user?
// the user touched the keypad
if (toggle)
{
toggle = NO;
// retrieve the strings in input fields
NSString *currencyField1Text = currencyField1.text;
NSString *currencyField2Text = currencyField2.text;
if (sender == currencyField1) {
currencyField1Text = [currencyField1Text stringByReplacingOccurrencesOfString:@"." withString:@""];
float currency = [currencyFieldText floatValue]/100;
currencyField1.text = [@"" stringByAppendingFormat:@"%0.2f", currency];
}
else if (sender == currencyField2) {
currencyField2Text = [currencyField2Text stringByReplacingOccurrencesOfString:@"." withString:@""];
NSDecimalNumber *currency2 = [[NSDecimalNumber decimalNumberWithString:currencyField2Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]];
currencyField2.text = [@"" stringByAppendingFormat:@"%@", currency2];
}
else {
NSLog(@"Some unexpected input");
}
}
else
{
toggle = YES;
}
} // end method calculateResults
currencyField1 代码段使用浮点数,currencyField2 段使用 NSDecimal。
currencyField1 段按需要工作:显示所有小数点后两位数字(即使使用删除键删除所有输入的数字);但是,它会遇到并完美地说明了在处理大货币值时使用浮点数的问题:当输入的数字超过 8 位时,会出现舍入错误。
currencyField2 段通过使用 NSDecimal 代替 float 来避免舍入错误问题;但是,它并不总是显示小数点后两位数的数字——这在使用删除键删除所有输入的数字时显示。我相信问题是由于这行代码:
currencyField2.text = [@"" stringByAppendingFormat:@"%@", currency2];
这是产生所需浮点格式的以下行的推论:
currencyField1.text = [@"" stringByAppendingFormat:@"%0.2f", currency];
所以,我认为我需要等效于 @"%0.2f" 来格式化“0”值 NSDecimalNumber 的显示。我已经在这个问题上待了这么多小时,以至于我很尴尬,但我就是想不通。
感谢任何帮助或指针。
编辑:我合并了 NSNumberFormatter 对象(类似于 Brad 在他的评论中描述的),这似乎已经解决了这个问题。但是,我想要一些关于重构代码的反馈,因为我已经让它工作了。这是修改后的代码:
// called when user touches a key or button
- (IBAction)processKeystrokes:(id)sender
{
static BOOL toggle = YES; // was this method triggered by the user?
// the user touched the keypad
if (toggle)
{
toggle = NO;
// retrieve the strings in input fields
NSString *currencyField1Text = currencyField1.text;
NSString *currencyField2Text = currencyField2.text;
// new code elements
NSNumberFormatter * nf = [[[NSNumberFormatter alloc] init]autorelease];
[nf setNumberStyle:NSNumberFormatterCurrencyStyle];
[nf setCurrencySymbol:@""];
[nf setCurrencyGroupingSeparator:@""];
if (sender == currencyField1) {
currencyField1Text = [currencyField1Text stringByReplacingOccurrencesOfString:@"." withString:@""];
NSDecimalNumber *currency = [[NSDecimalNumber decimalNumberWithString:currencyField1Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]];
currencyField1.text = [nf stringFromNumber:currency];
}
else if (sender == currencyField2) {
currencyField2Text = [currencyField2Text stringByReplacingOccurrencesOfString:@"." withString:@""];
NSDecimalNumber *currency2 = [[NSDecimalNumber decimalNumberWithString:currencyField2Text] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]];
currencyField2.text = [nf stringFromNumber:currency2];
}
else {
NSLog(@"Some unexpected input");
}
}
else
{
toggle = YES;
}
} // end method calculateResults
它解决了我最初的问题,但我会很感激任何关于如何改进它的建议。谢谢。
【问题讨论】:
标签: iphone cocoa-touch keyboard decimal nsdecimalnumber