试图格式化的UITextField表现得像在仅适用于iOS数字输入货币计算器(Trying to f

2019-08-17 07:19发布

我有一个UITextField在我的应用程序,应该从用户只接收数字输入。 这个数字输入应该代表的货币(即只有小数点后两位),拥有0.00的默认值时,已经进入了什么。 我也想有一个“$”符号是在最左边,右对齐的数量,使得数量从右侧移到左侧像这样的:

输入数字“1234.56”时,如。

1. $ 0.00元

2. US $ 0.01。

3. $ 0.12。

4. $ 1.23

5,$ 12.34

6. $; 123.45&。

7. $ 1,234.56。

8.等等...

我有UITextField右对齐,以便它已经结束了,从右侧移至左侧的数字。 但是,我需要把“$” 给出UITextField里面,我想默认值0.00进行修改,以在一个时间由用户一个数字输入的号码。 用户应该不必输入小数点,因为它应该已经在文本框保持其位置。 那么我想多少有一个“”被自动输入到每三位数字分开。 我想申请要做到这一点,因为用户输入数字 ,并且进入的一切,当后来没有格式化。 我会怎么做呢? 我见过很多人说我用NSNumberFormatter ,但我想知道我怎么使用它结合UITextField使得其格式上飞数字文本,如上所述?

我发现在计算器上发布前段时间以下问题:

什么是带小数点输入数值的最佳方法?

但我想知道如何真正纳入它作为一个解决我的问题。

Answer 1:

这里是一个很好的方式来做到这一点。 请记住,你的UITextField设定中自viewDidLoad方法和你的头文件必须符合UITextFieldDelegate协议

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    NSString *cleanCentString = [[textField.text componentsSeparatedByCharactersInSet: [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
    NSInteger centValue = [cleanCentString intValue];
    NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
    NSNumber *myNumber = [f numberFromString:cleanCentString];
    NSNumber *result;

    if([textField.text length] < 16){
        if (string.length > 0)
        {
            centValue = centValue * 10 + [string intValue];
            double intermediate = [myNumber doubleValue] * 10 +  [[f numberFromString:string] doubleValue];
           result = [[NSNumber alloc] initWithDouble:intermediate];
        }
        else
        {
            centValue = centValue / 10;
            double intermediate = [myNumber doubleValue]/10;
            result = [[NSNumber alloc] initWithDouble:intermediate];
        }

        myNumber = result;
         NSLog(@"%ld ++++ %@", (long)centValue, myNumber);
            NSNumber *formatedValue;
            formatedValue = [[NSNumber alloc] initWithDouble:[myNumber doubleValue]/ 100.0f];
            NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
            [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
            textField.text = [_currencyFormatter stringFromNumber:formatedValue];
            return NO;
    }else{

        NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
        [_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        textField.text = [_currencyFormatter stringFromNumber:00];

        UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Deposit Amount Limit"
                                                       message: @"You've exceeded the deposit amount limit. Kindly re-input amount"
                                                      delegate: self
                                             cancelButtonTitle:@"Cancel"
                                             otherButtonTitles:@"OK",nil];

        [alert show];
        return NO;
    }
    return YES;
}


Answer 2:

对于SWIFT 3回答更新

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2

        if string.characters.count > 0 {
            amountTypedString += string
            let decNumber = NSDecimalNumber(string: amountTypedString).multiplying(by: 0.01)
            let newString = "$" + formatter.string(from: decNumber)!
            textField.text = newString
        } else {
            amountTypedString = String(amountTypedString.characters.dropLast())
            if amountTypedString.characters.count > 0 {
                let decNumber = NSDecimalNumber(string: amountTypedString).multiplying(by: 0.01)
                let newString = "$" +  formatter.string(from: decNumber)!
                textField.text = newString
            } else {
                textField.text = "$0.00"
            }

        }
        return false

    }

    func textFieldShouldClear(_ textField: UITextField) -> Bool {
        amountTypedString = ""
        return true
    }


Answer 3:

这是我在斯威夫特的解决方案。 我的做法是跟踪输入的号码,并通过0.01相乘,并设置与使用NSNumberFormatter 2个小数点的结果数量。 请注意,我有文本框的键盘设置为数字键盘。

amountTextfield?.keyboardType = UIKeyboardType.NumberPad

var amountTypedString = ""

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let formatter = NSNumberFormatter()
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2

    if string.characters.count > 0 {
        amountTypedString += string
        let decNumber = NSDecimalNumber(float: Float(amountTypedString)!).decimalNumberByMultiplyingBy(0.01)
        let newString = "$" + formatter.stringFromNumber(decNumber)!
        textfield.text = newString
    } else {
        amountTypedString = String(amountTypedString.characters.dropLast())
        if amountTypedString.characters.count > 0 {
            let decNumber = NSDecimalNumber(float: Float(amountTypedString)!).decimalNumberByMultiplyingBy(0.01)
            let newString = "$" +  formatter.stringFromNumber(decNumber)!
            textfield.text = newString
        } else {
            textfield.text = "$0.00"
        }

    }
    return false

}

func textFieldShouldClear(textField: UITextField) -> Bool {
    amountTypedString = ""
    return true
}


Answer 4:

您可能需要检查的UITextFieldDelegate协议。 通过分配的东西(最常用的视图控制器类)作为的UITextField的委托,你就可以从控制接收交互式文本输入事件。 特别是:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string

通过从该方法返回NO,您可以防止应用用户按下按键的文本字段。

但是,即使你返回NO没有什么可以阻止你使用传递给委托方法做你自己的代码中的文本字段内容的操作信息。

在伪码形式:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (string-contains-number) {
        alter textfield.text to be what it should be now, adding the number;
    }
    else {
        string contains something you don't wan the user typing, so ignore it.
    }

    // Tell iOS not to apply the user's change (since you just did by 
    // updating the text yourself:
    return NO;
}

免责声明:我没有写实际的代码进行测试,所以它可能是改变这种委托方法中的代码导致另一个shouldChangeCharactersInRange:消息开火。 我不相信是这样的话,虽然。 当你改变代码的文本,我不相信委托事件触发。

这显然是不作为已经实现了许多文本输入框(我回想到几年Visual Basic程序设计的,现在......)的所有规则的自定义控制好。 但我不知道任何这样的控制的,有人的书面和开源。



Answer 5:

我已经采取了从朱利安的答案,并具有不同的货币格式都支持修改它,以便其他语言环境。 我还保存再利用的数字格式化,使他们分别是一个昂贵的操作时间没有创造。

溢流通过忽略,将导致所存储的值溢出任何输入处理。

这种解决方案假定文本是仅在文本字段的输入端,因此仅将在端部无论在哪里之前输入文本光标是操作。

let outputFormatter: NSNumberFormatter = {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .CurrencyStyle
    if formatter.maximumFractionDigits > 0 {
        formatter.multiplier = pow(10, -CGFloat(formatter.maximumFractionDigits))
    }
    return formatter
}()

let inputFormatter: NSNumberFormatter = {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .DecimalStyle
    return formatter
}()

private var value: UInt = 0

var currencyValue: NSDecimalNumber {
    let exponent = Int16(truncatingBitPattern: outputFormatter.maximumFractionDigits)
    return NSDecimalNumber(mantissa: UInt64(value), exponent: -exponent, isNegative: false)
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.isEmpty {
        /* User pressed backspace, shift right one space. */
        value /= 10
    } else if let number = inputFormatter.numberFromString(string)?.unsignedIntegerValue {
        /* User entered a number, shift left one space and add. */
        let shiftedValue = UInt.multiplyWithOverflow(value, 10)
        let addedValue = UInt.addWithOverflow(shiftedValue.0, number)
        if !shiftedValue.overflow && !addedValue.overflow {
            value = addedValue.0
        }
    }

    textField.text = outputFormatter.stringFromNumber(NSDecimalNumber(unsignedInteger: value))
    return false
}

func textFieldShouldClear(textField: UITextField) -> Bool {
    value = 0
    return true
}

在各种语言环境操场使用这给了我这些结果 (对不起,不能直接嵌入尚未)。



文章来源: Trying to format a UITextField to behave like a currency calculator for only numeric input in iOS