【问题标题】:Format a UITextField for currency为货币格式化一个 UITextField
【发布时间】:2014-01-12 18:25:23
【问题描述】:

我的应用程序上有一个 UITextField,它只接收来自用户的数字输入。此数字输入表示货币,默认值为 0.00。

当用户输入数字时,我想创建一个类似于掩码的东西来格式化 UITextField。例如:

9 变为 $0,09 99 变为 $0,99 999 变成 $999,99

下面的代码效果很好,但由于我使用的是整数和浮点值,因此应用程序最终会在某个点之后显示错误的值。例如:

999999999 变为 100000000

这是因为浮点数和整数不够精确,应该使用 NSDEcimalNumber。关键是我不知道如何将我的整数和浮点值替换为 NSDecimalNumber。

有人可以帮我解决这个问题吗?我花了一些时间在网上搜索解决方案,但没有找到适合我的需求和大量遇到相同问题的人。

代码如下:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.tag == 1){
    NSString *cleanCentString = [[textField.text componentsSeparatedByCharactersInSet: [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
    NSInteger centValue= cleanCentString.integerValue;

    if (string.length > 0)
    {
        centValue = centValue * 10 + string.integerValue;
    }
    else
    {
        centValue = centValue / 10;
    }

    NSNumber *formatedValue;
    formatedValue = [[NSNumber alloc] initWithFloat:(float)centValue / 100.0f];
    NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
    [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    textField.text = [_currencyFormatter stringFromNumber:formatedValue];
    return NO;
}

if (textField.tag == 2){
    // Nothing for now
}

return YES;
}

【问题讨论】:

  • 你有一个更大的问题。您假设输入的货币是货币价值的 100 分之一,例如美分。例如,日本人不会高兴,因为日元只是整日元。您应该在将数字格式化程序设置为货币样式后询问它,看看它设置了多少个小数位。
  • 你是对的,rmaddy。待办事项不断增加=D
  • 就我个人而言,我认为最好让用户输入一个没有“随用随取”处理的原始数字。在用户离开文本字段之前,不要格式化原始数字。作为用户,当我真正想要小数时,我宁愿输入小数分隔符。如果我输入9,那么我的意思是九美元,而不是九美分。如果我想要 9 美分,那么我想输入 .09。让后处理格式为$0.09 或我完成输入后的任何内容。不要让我输入900 来获得九美元。但这只是一种观点。
  • 嗯,这是一个有趣的观点。也许会更好。
  • @Carlos 我使用你的方法并遇到了同样的问题。我检查了以下答案,但有些我无法解决。你能帮我解决这个问题吗?你能用更正的方法编辑相同的方法吗?

标签: ios objective-c uitextfield


【解决方案1】:

实现UITextFieldDelegate并添加下一个方法:

斯威夫特:

let currencySign = "$"

// Adds $ before the text, e.g. "1" -> "$1" and allows "." and ","
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
    {
    var value = textField.text

    var newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
    var components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "1234567890,.").invertedSet)

    var decimalString = "".join(components) as NSString
    var length = decimalString.length

    if length > 0 {
        value = "\(currencySign)\(decimalString)"
    }
    else {
        value = ""
    }
    textField.text = value
}

// Formats final value using current locale, e.g. "130,50" -> "$130", "120.70" -> "$120.70", "5" -> "$5.00"
func textFieldDidEndEditing(textField: UITextField) {
        var value = textField.text
        var components = value.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "1234567890,.").invertedSet)
        var decimalString = "".join(components) as NSString

        let number = NSDecimalNumber(string: decimalString, locale:NSLocale.currentLocale())

        var formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        formatter.locale = NSLocale.currentLocale()

        if let formatedValue = formatter.stringFromNumber(number) {
            textField.text = formatedValue
        }
        else {
            textField.text = ""
        }
}

【讨论】:

    【解决方案2】:

    您可以通过以下方式将整数或双精度/浮点值转换为字符串:

    NSString *str = [@(myInt) stringValue];
    NSString *str1 = [[NSNumber numberWithFloat:myFloat] stringValue];
    

    之后,您可以通过多种方式将字符串转换为 NSDecimalNumber。喜欢:

    NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"];
    NSLog(@"%@", number);
    NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithString:@"100.1" locale:NSLocale.currentLocale];
    NSLog(@"%@",num);
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [formatter setLocale:[NSLocale currentLocale]];
    NSLog(@"%@", [formatter stringFromNumber:number]);
    

    NSNumberFormatter 将帮助您进行正确的格式化。请阅读NSDecimalNumberNSNumberFormatter 的苹果页面。 NSNumberFormatter 包含一个名为“配置货币格式”的部分。我没有尝试过,但它似乎可以帮助你。

    让我知道这是否有帮助.. :)

    【讨论】:

    • 谢谢,拉沙德!这可以很好地将值从字符串转换为 NSDecimalNumber,即使对于货币也是如此。但现在我得到'NSDecimalNumberOverflowException',因为我正在这样做:result = [decimalValue decimalNumberByMultiplyingBy:base];结果 = [decimalValue decimalNumberByDividingBy:base];.
    • @carlos >> 你解决问题了吗?我正在检查我的答案。所以我才问。 :)
    • 我决定稍微改变一下,让用户输入一个原始数字。但我没有找到解决 'NSDecimalNumberOverflowException 错误 =/
    • 如果操作中使用的数字不是有效数字,通常会导致。仔细检查您的号码,您可以在执行指令之前检查:[NSDecimalNumber notANumber]。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-25
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    相关资源
    最近更新 更多