Format currency in textfield in Swift on input

前端 未结 7 1798
一生所求
一生所求 2021-02-08 07:52

I am trying to format currency input in a textfield in Swift as the user inputs it.

So far, I can only format it successfully when the user finishes inputting:



        
相关标签:
7条回答
  • 2021-02-08 08:29

    For Swift 3.0

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            // Construct the text that will be in the field if this change is accepted
    
            switch string {
            case "0","1","2","3","4","5","6","7","8","9":
                currentString += string
                formatCurrency(currentString)
            default:
                if string.characters.count == 0 && currentString.characters.count != 0 {
                    currentString = String(currentString.characters.dropLast())
                    formatCurrency(currentString)
                }
            }
            return false    }
    
        func formatCurrency(_ string: String) {
            print("format \(string)")
            let formatter = NumberFormatter()
            formatter.numberStyle = .currency
            formatter.locale = findLocaleByCurrencyCode("NGN")
            let numberFromField = (NSString(string: currentString).doubleValue)/100
            let temp = formatter.string(from: NSNumber(value: numberFromField))
            self.amountTextField.text = String(describing: temp!.characters.dropFirst())
        }
    
    func findLocaleByCurrencyCode(_ currencyCode: String) -> Locale? {
    
        let locales = Locale.availableIdentifiers 
        var locale: Locale?     
        for   localeId in locales {     
          locale = Locale(identifier: localeId)     
          if let code = (locale! as NSLocale).object(forKey: NSLocale.Key.currencyCode) as? String { 
            if code == currencyCode {
                    return locale       
            }   
        } 
    }    
    return locale }
    
    0 讨论(0)
  • 2021-02-08 08:29

    this works for me using NSNumberFormatter...

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
        // Construct the text that will be in the field if this change is accepted
        var oldText = textField.text as NSString
        var newText = oldText.stringByReplacingCharactersInRange(range, withString: string) as NSString!
        var newTextString = String(newText)
    
        let digits = NSCharacterSet.decimalDigitCharacterSet()
        var digitText = ""
        for c in newTextString.unicodeScalars {
            if digits.longCharacterIsMember(c.value) {
                digitText.append(c)
            }
        }
    
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        formatter.locale = NSLocale(localeIdentifier: "en_US")
        var numberFromField = (NSString(string: digitText).doubleValue)/100
        newText = formatter.stringFromNumber(numberFromField)
    
        textField.text = newText
    
        return false
    }
    
    0 讨论(0)
  • 2021-02-08 08:41

    I worked out a normal currency format ( eg 1 is as $1.00, 88885 is as $8,8885.00 and 7555.8569 as $7,555.86.

    @IBAction func lostpropertyclicked(sender: AnyObject) {
        var currentString = ""
        currentString = amountTF.text
        formatCurrency(string: currentString)
    }
    
    func formatCurrency(#string: String) {
        println("format \(string)")
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        formatter.locale = NSLocale(localeIdentifier: "en_US")
        var numberFromField = (NSString(string: currentString).doubleValue)
        currentString = formatter.stringFromNumber(numberFromField)!
        println(currentString )
    }
    
    0 讨论(0)
  • 2021-02-08 08:41

    Based on @Robert answer. Updated for Swift 2.0

    //Textfield delegates
    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // return NO to not change text
    
        switch string {
        case "0","1","2","3","4","5","6","7","8","9":
            currentString += string
            formatCurrency(currentString)
        default:
            if string.characters.count == 0 && currentString.characters.count != 0 {
                currentString = String(currentString.characters.dropLast())
                formatCurrency(currentString)
            }
        }
        return false
    }
    
    func formatCurrency(string: String) {
        print("format \(string)")
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        formatter.locale = NSLocale(localeIdentifier: "en_US")
        let numberFromField = (NSString(string: currentString).doubleValue)/100
        self.amountField.text = formatter.stringFromNumber(numberFromField)
        print(self.amountField.text )
    }
    
    0 讨论(0)
  • 2021-02-08 08:44

    This worked for me: Naming of the variables need to be improved though. Multiplying by 10 was easy but figuring out how to divide by 10 and round down was tricky with the pointers.

        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .currency
    
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField == amountTextField {
            guard let text = textField.text else {return true}
    
            let oldDigits = numberFormatter.number(from: text) ?? 0
            var digits = oldDigits.decimalValue
    
            if let digit = Decimal(string: string) {
                let newDigits: Decimal = digit / 100
    
                digits *= 10
                digits += newDigits
            }
            if range.length == 1 {
                digits /= 10
                var result = Decimal(integerLiteral: 0)
                NSDecimalRound(&result, &digits, 2, Decimal.RoundingMode.down)
                digits = result
            }
    
            textField.text = NumberFormatter.localizedString(from: digits as NSDecimalNumber, number: .currency)
            return false
        } else {
            return true
        }
    }
    
    0 讨论(0)
  • 2021-02-08 08:44

    Swift 5

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // return NO to not change text
    
        switch string {
        case "0","1","2","3","4","5","6","7","8","9":
            currentString += string
            formatCurrency(string: currentString)
        default:
            if string.count == 0 && currentString.count != 0 {
                currentString = String(currentString.dropLast())
                formatCurrency(string: currentString)
            }
        }
        return false
    }
    
    func formatCurrency(string: String) {
        print("format \(string)")
        let formatter = NumberFormatter()
        formatter.numberStyle = NumberFormatter.Style.currency
        formatter.locale = NSLocale(localeIdentifier: "en_US") as Locale
        let numberFromField = (NSString(string: currentString).doubleValue)/100
        //replace billTextField with your text field name
        self.billTextField.text = formatter.string(from: NSNumber(value: numberFromField))
        print(self.billTextField.text ?? "" )
    }
    
    0 讨论(0)
提交回复
热议问题