How to input currency format on a text field (from right to left) using Swift?

前端 未结 9 1041
甜味超标
甜味超标 2020-11-22 01:57

I have a number let’s say 0.00.

  • When the user taps 1. We should have 0.01
  • When the user taps 2. We should display 0.
相关标签:
9条回答
  • 2020-11-22 02:25

    My final code thanks for your help

    extension Double {
                var twoDigits: Double {
                    let nf = NSNumberFormatter()
                    nf.numberStyle = NSNumberFormatterStyle.DecimalStyle
                    nf.minimumFractionDigits = 2
                    nf.maximumFractionDigits = 2
                    return self
                }
        }
        var cleanText:String!
                let number:String = sender.currentTitle as String!
                if(amountDisplay.text != nil)
                {
                    cleanText = String(Array(amountDisplay.text!).map{String($0)}.filter{ $0.toInt() != nil }.map{Character($0)} ) as String
                    cleanText = cleanText + number
                }else{
                    cleanText = number
                }
    
                amount = (Double(cleanText.toInt()!) / 100).twoDigits
                formatter.locale = NSLocale(localeIdentifier: currencies[current_currency_index])
                amountDisplay.text = "\(formatter.stringFromNumber(amount!)!)"
    
    0 讨论(0)
  • 2020-11-22 02:27

    After a lot of trial and error with the suggested answers, I found a pretty straight forward solution:

    The setup for the textField needs to be called in your view's setup.

    In the switch statement, if the user puts in a number between 0 and 9, the number is added to the previous string value. The default case covers the backspace button and removes the last character from the string.

    The locale for the numberFormatter is set to current, so it works with different currencies.

    func setupTextField() {
            textField.delegate = self
            textField.tintColor = .clear
            textField.keyboardType = .numberPad
    }
    
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        setFormattedAmount(string)
        
        return false
    }
    
    private func setFormattedAmount(_ string: String) {
        switch string {
        case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
            amountString = amountString + string
        default:
            if amountString.count > 0 {
                amountString.removeLast()
            }
        }
        
        let amount = (NSString(string: amountString).doubleValue) / 100
        textField.text = formatAmount(amount)
    }
    
    private func formatAmount(_ amount: Double) -> String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = .current
        
        if let amount = formatter.string(from: NSNumber(value: amount)) {
            return amount
        }
        
        return ""
    }
    
    0 讨论(0)
  • 2020-11-22 02:36

    For Swift 3. Input currency format on a text field (from right to left)

    override func viewDidLoad() {
        super.viewDidLoad()
    
        textField.addTarget(self, action: #selector(myTextFieldDidChange), for: .editingChanged)
    }
    
    func myTextFieldDidChange(_ textField: UITextField) {
    
        if let amountString = textField.text?.currencyInputFormatting() {
            textField.text = amountString
        }
    }
    
    extension String {
    
        // formatting text for currency textField
        func currencyInputFormatting() -> String {
    
            var number: NSNumber!
            let formatter = NumberFormatter()
            formatter.numberStyle = .currencyAccounting
            formatter.currencySymbol = "$"
            formatter.maximumFractionDigits = 2
            formatter.minimumFractionDigits = 2
    
            var amountWithPrefix = self
    
            // remove from String: "$", ".", ","
            let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
            amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count), withTemplate: "")
    
            let double = (amountWithPrefix as NSString).doubleValue
            number = NSNumber(value: (double / 100))
    
            // if first number is 0 or all numbers were deleted
            guard number != 0 as NSNumber else {
                return ""
            }
    
            return formatter.string(from: number)!
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:36

    I started with Leo Dabus' answer (which didn't work out of the box for me) and in the process of trying to simplify and make it work ended up with this, which I think is pretty lean & clean if I do say so myself

    0 讨论(0)
  • 2020-11-22 02:39

    Here is a code for swift 2

    @IBOutlet weak var txtAmount: UITextField!
    
    //MARK: - UITextField Delegate -
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{
    
            if string.characters.count == 0 {
                return true
            }
    
            let userEnteredString = textField.text ?? ""
            var newString = (userEnteredString as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString
            newString = newString.stringByReplacingOccurrencesOfString(".", withString: "")
    
            let centAmount : NSInteger = newString.integerValue
            let amount = (Double(centAmount) / 100.0)
    
            if newString.length < 16 {
                let str = String(format: "%0.2f", arguments: [amount])
                txtAmount.text = str
            }
    
            return false //return false for exact out put
        }
    

    Note : Connect delegate for textField from storyboard or programatically

    0 讨论(0)
  • 2020-11-22 02:41

    Thanks to everyone here. From all the answers here I managed to come out with mine.

    First I set up the initial value of the textField to be:

    private func commonInit() { 
        amountTextField.text = "0.00"
    }
    

    Then I use the UITextFieldDelegate to get the input value and the current textview.text:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        //Need to check if the textfield.text can be evaluated as number or not before passing it to the function
        //Get the current text value, and current user input and pass it to the 
        let formattedAmount = formatAmount(oldAmount: textField.text, userInput: string)
        textField.text = formattedAmount
        return false
    }
    

    Here go my private function to format the number to move from right to left:

    private func formatAmount(currentText: String, userInput: String) -> String {
        let amount = currentText.components(separatedBy: ".")
        var intValue: String = amount[0]
        var decimalValue: String = amount[1]
        
    
        //backspace registered, need to move the number to the right
        if userInput.isEmpty {
            decimalValue.remove(at: decimalValue.index(before: decimalValue.endIndex))
            decimalValue = intValue.last!.string + decimalValue
            intValue.remove(at: intValue.index(before: intValue.endIndex))
            if intValue.isEmpty {
                intValue = "0"
            }
        } else {
            
            //Need to consider if user paste value
            if userInput.count > 2 {
                decimalValue = String(userInput.suffix(2))
                intValue = String(userInput.dropLast(2))
            } else {
                decimalValue = rmAmount[1] + userInput
                
                //Add to int value (move to the right)
                intValue = intValue + decimalValue.first!.string
                
                if Int(intValue) == 0 {
                    intValue = "0"      //00 -> 0
                } else if intValue.first == "0" {
                    //remove 0 from at the first position in intValue
                    intValue.remove(at: intValue.startIndex)    //01 -> 1
                }
                
                //Remove tenth place from decimal value since it goes to Int already
                decimalValue.remove(at: decimalValue.startIndex)
            }
        }
        return intValue + "." + decimalValue
    }
    

    This is basically it. Other extra implementations can be added by your own initiatives. Let me know if there is any problem with my implementation.

    PS: This is of course only works for certain currency only, in my case, my apps is set up only for that local so thats why I use this way.

    0 讨论(0)
提交回复
热议问题