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 对象(类似于布拉德在他的评论中描述的),这似乎已经解决了这个问题。但是,我想要一些关于重构代码的反馈,因为我已经让它工作了。这是修改后的代码:
// 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
它解决了我最初的问题,但我将不胜感激有关如何改进它的任何建议。谢谢。