我正在尝试做一些我认为相当简单的事情:让用户输入一个美元金额,将该金额存储在NSNumber(NSDecimalNumber?)中,然后再显示格式化为货币的金额。
我的麻烦不在于setNumberStyle:NSNumberFormatterCurrencyStyle并将浮动显示为货币。问题更多的是所述numberFormatter如何与这个UITextField一起工作。我可以找到一些例子。 This thread从11月开始,this one给了我一些想法,但给我留下了更多问题。
我正在使用UIKeyboardTypeNumberPad键盘,并了解我应该在显示的字段中显示$ 0.00(或任何本地货币格式),然后当用户输入数字以移动小数位时:
然后[numberFormatter numberFromString:textField.text]应该给我一个值,我可以存储在我的NSNumber变量中。
可悲的是,我仍然在苦苦挣扎:这真的是最好/最简单的方法吗?如果是这样,也许有人可以帮助我实施?我觉得UITextField可能需要一个代理响应每个按键,但不知道什么,在哪里以及如何实现它?!任何示例代码?我非常感谢!我搜索过高低......
Edit1:所以我正在研究NSFormatter的 stringForObjectValue:以及我能找到的最接近benzado建议的内容: UITextViewTextDidChangeNotification 。真的很难在其中任何一个上找到示例代码...所以,如果你知道在哪里看,请告诉我?
答案 0 :(得分:10)
我的解决方案:
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
// Clear all characters that are not numbers
// (like currency symbols or dividers)
NSString *cleanCentString = [[textField.text
componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
// Parse final integer value
NSInteger centAmount = cleanCentString.integerValue;
// Check the user input
if (string.length > 0)
{
// Digit added
centAmount = centAmount * 10 + string.integerValue;
}
else
{
// Digit deleted
centAmount = centAmount / 10;
}
// Update call amount value
[_amount release];
_amount = [[NSNumber alloc] initWithFloat:(float)centAmount / 100.0f];
// Write amount with currency symbols to the textfield
NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
[_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[_currencyFormatter setCurrencyCode:@"USD"];
[_currencyFormatter setNegativeFormat:@"-¤#,##0.00"];
textField.text = [_currencyFormatter stringFromNumber:_amount];
[_currencyFormatter release]
// Since we already wrote our changes to the textfield
// we don't want to change the textfield again
return NO;
}
答案 1 :(得分:3)
这是我现在必须写的那个粗略的攻击计划。诀窍是输入隐藏的UITextField并使用格式化的值更新UILabel作为用户输入。
在每次按键时,标签都会更新,因此当用户真正编辑隐藏文本字段时,用户会觉得她正在编辑格式化的值。鬼鬼祟祟!
答案 2 :(得分:1)
嗯,我认为这样更好:
- (void)viewWillDisappear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; }
-(void)viewDidAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil];
}
-(void)textDidChanged:(NSNotification *)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
UITextField * textField= [notification object];
NSString * sinPesos= [textField.text stringByReplacingOccurrencesOfString:@"$" withString:@""];
NSString * sinPuntos= [sinPesos stringByReplacingOccurrencesOfString:@"." withString:@""];
float monto = [sinPuntos floatValue];
monto= monto/100;
NSString * cardText= [[self montoFormatter] stringFromNumber:[NSNumber numberWithDouble:monto]];
textField.text = ([cardText isEqualToString: @"0"] ? @"":cardText);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil];
}
-(NSNumberFormatter *)montoFormatter{
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
return [numberFormatter autorelease];
}
尝试一下:)
答案 3 :(得分:1)
由于我很懒,我无法忍受我的输入重新格式化“帮我出去”,我说:
让他们输入一个十进制数字。当他们离开现场时,重新格式化。
答案 4 :(得分:0)
嗯,这有点晚了但我觉得无论如何我都会试一试。这可能是一种解决方法,可能是凌乱的代码,但它对我有用。我在IB中连接了一个标签和一个隐藏的文本字段,我使用UITextFieldDelegate委托编写了这段代码。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == fineHiddenTextField) {
NSString *fineText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([fineText length] == 0) {
NSString *emptyFine = @"0.00";
float fineValue = [emptyFine floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else if ([fineText length] == 1) {
NSString *firstDec = [NSString stringWithFormat:@"0.0%@", fineText];
float fineValue = [firstDec floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else if ([fineText length] == 2) {
NSString *secondDec = [NSString stringWithFormat:@"0.%@", fineText];
float fineValue = [secondDec floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else {
int decimalPlace = [fineText length] - 2;
NSString *fineDollarAmt = [fineText substringToIndex:decimalPlace];
NSString *fineCentsAmt = [fineText substringFromIndex:decimalPlace];
NSString *finalFineValue = [NSString stringWithFormat:@"%@.%@", fineDollarAmt, fineCentsAmt];
float fineValue = [finalFineValue floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
}
//fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
return YES;
}
}
不完全是最好的,但它确实完成了工作。最初的if语句只是为了确保这只发生在这个特定的textField上(因为整个同一页面都有多个。)这段代码用于输入金钱(罚款金额)我想要它简单易用。只需将标签设置为从右侧对齐即可。
我现在对咖啡有点兴趣,但我会回答你的任何问题。 :)
答案 5 :(得分:0)
这是我的解决方案!
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
float valorUnit = [textField.text floatValue];
if( string.length > 0)
{
float incremento = [string floatValue];
valorUnit = valorUnit * 10.f + (incremento/100.f);
NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit];
if (valorUnit > 0.f && valorUnit < 10.f) {
textField.text = [strVal substringToIndex:3];
}
else if (valorUnit < 100.f && valorUnit >= 10.f)
{
textField.text = [strVal substringToIndex:4];
}
else if (valorUnit >=100.f && valorUnit <1000.f)
{
textField.text = [strVal substringToIndex:5];
}
else {
return NO;
}
}
else {
valorUnit = (valorUnit/10.f);
NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit];
if (valorUnit > 0.f && valorUnit < 10.f) {
textField.text = [strVal substringToIndex:5];
}
else if (valorUnit < 100.f && valorUnit >= 10.f)
{
textField.text = [strVal substringToIndex:6];
}
else if (valorUnit >=100.f && valorUnit <1000.f)
{
textField.text = [strVal substringToIndex:7];
}
else {
return NO;
}
}
return YES;
}
答案 6 :(得分:0)
我写了一个开源UITextField
子类来处理这个问题,可以在这里找到:
https://github.com/TomSwift/TSCurrencyTextField
我采用的方法类似于Lars Schneider在其流行答案中的建议。但是我的版本完全封装在你可以在任何地方使用的可重用组件中,就像UITextField一样。如果您选择实现任何UITextFieldDelegate方法,但这不是必需的。