UITextField显示格式为不带小数的货币

时间:2016-12-21 05:46:17

标签: ios swift uitextfield

我正在尝试制作一个UITextField,即使用户正在编辑,输入也会以货币格式永久显示。它应该像:

$0

用户类型1

$1

用户类型2

$12

用户输入0

$120

用户输入0

$1,200

用户输入0

$12,000

我设法使用NumberFormatter

获取最终格式
textField.text = (numberFormatter.string(from: NSNumber(value: Int(textField.text!)!)))?.components(separatedBy: ".")[0]

但是一旦我在textField中格式化文本,后续输入将导致如下错误:

$1,000

用户输入0

$1,0000 //number formatter cannot recognise this as a format of currency

无论如何,我可以操纵输入以允许用户只需要键入数字,但值以适当的货币格式显示,并带有符号加逗号 - 例如$ 1,200,000。无论数字量多少 - 但逻辑上最多10位就足够了。

我当前的textField shouldChangeCharactersInRange是这样的:

    textField.text = numberFormatter.number(from: textField.text!)?.description

    if(range.length == 1){  //Backspace
        if(textField.text?.characters.count == 1){
            textField.text = "$0"
            return false
        }
        return true
    }
    if(string.trimmingCharacters(in: CharacterSet.decimalDigits.inverted) == ""){
        textField.text = (numberFormatter.string(from: NSNumber(value: Int(textField.text!)!)))?.components(separatedBy: ".")[0]
        return false
    }
    if(string == ".") {
        textField.text = (numberFormatter.string(from: NSNumber(value: Int(textField.text!)!)))?.components(separatedBy: ".")[0]
        return false
    }

    textField.text = (numberFormatter.string(from: NSNumber(value: Int(textField.text!.append(string)!)!)))?.components(separatedBy: ".")[0]
    return false

3 个答案:

答案 0 :(得分:4)

尝试以下代码

extension ViewController: UITextFieldDelegate {

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

        let text: NSString = (textField.text ?? "") as NSString
        let finalString = text.replacingCharacters(in: range, with: string)

        // 'currency' is a String extension that doews all the number styling
        amountTextField.text = finalString.currency

        // returning 'false' so that textfield will not be updated here, instead from styling extension
        return false
    }
}

extension String {
    var currency: String {
        // removing all characters from string before formatting
        let stringWithoutSymbol = self.replacingOccurrences(of: "$", with: "")
        let stringWithoutComma = stringWithoutSymbol.replacingOccurrences(of: ",", with: "")

        let styler = NumberFormatter()
        styler.minimumFractionDigits = 0
        styler.maximumFractionDigits = 0
        styler.currencySymbol = "$"
        styler.numberStyle = .currency

        if let result = NumberFormatter().number(from: stringWithoutComma) {
            return styler.string(from: result)!
        }

        return self
    }
}

答案 1 :(得分:2)

//  ViewController.swift
//  TextfieldDemo
//
//  Created by piyush sinroja on 21/12/16.


import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var txtDigit: UITextField!

    var strDigit: String = String()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let label = UILabel(frame: CGRect(x :0,y :0,width :10,height: 10))
        label.text = "$"
        self.txtDigit.leftViewMode = .always
        self.txtDigit.leftView = label

        txtDigit.layer.cornerRadius = 4.0
        txtDigit.layer.masksToBounds = true
        txtDigit.layer.borderColor = UIColor.lightGray.cgColor
        txtDigit.layer.borderWidth = 1.0
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {

    }

    func textFieldDidEndEditing(_ textField: UITextField) {

    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        return true
    }

    func textField(_ textFieldToChange: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if  textFieldToChange == txtDigit{
            let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
            let compSepByCharInSet = string.components(separatedBy: aSet)
            let numberFiltered = compSepByCharInSet.joined(separator: "")

            if numberFiltered == "" {
                let new  = txtDigit.text!
                let fsf = new.substring(to: new.index(new.endIndex, offsetBy: -1))
                let currentString = fsf
                let findStr = commaStrSet(currentString: currentString)
                txtDigit.text = findStr
                return false
            }
            else{
                let currentString = (textFieldToChange.text! as NSString)
                    .replacingCharacters(in: range, with: string)
                let findStr = commaStrSet(currentString: currentString)
                txtDigit.text = findStr
            }
        }
        return false
    }

    func commaStrSet(currentString: String) -> String {
        var replaceStr = currentString.replacingOccurrences(of: ",", with: "")
        let length = replaceStr.characters.count
        switch length {
        case 4:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 1))
        case 5:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 2))
        case 6:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 1))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 5))
        case 7:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 2))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 5))
        case 8:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 1))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 4))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 7))
        case 9:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 2))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 5))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 8))
        case 10:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 1))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 4))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 7))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 10))
        case 11,12,13,14,15:
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 1))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 4))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 7))
            replaceStr.insert(",", at: replaceStr.index(replaceStr.startIndex, offsetBy: 10))
        default:
            break
        }

        return replaceStr
    }
}

答案 2 :(得分:0)

您可以使用UITextField的leftView和rightView属性,如下所示:这只会显示" $"输入字段左侧的符号。

override func viewDidLoad() {
        super.viewDidLoad()

        let label = UILabel(frame: CGRect(x :0,y :0,width :10,height: 10))
        label.text = "$"

        self.moneyTextField.leftViewMode = .always
        self.moneyTextField.leftView = label

    }