1

I am trying to format the textfield's input in currency standard format using its delegate method but the found solution is not upto the desire. I also found some solutions but nowhere i found the expected solution.

Requirements:

UITextField's Input: 300000

Getting: 30,0000

Desired Output: 300,000

Using code:

//MARK:- textfield delegate method
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
    
    guard let textFieldHasText = (textField.text), !textFieldHasText.isEmpty else {
        //early escape if nil
        return true
    }
    
    if textField == self.reqCourps || textField == self.presentInvest{
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        
        //remove any existing commas
        let textRemovedCommma = textFieldHasText.replacingOccurrences(of: ",", with: "")
        
        //update the textField with commas
        let formattedNum = formatter.string(from: NSNumber(value: Int(textRemovedCommma)!))
        
        textField.text = formattedNum
    }
    
    
    guard let text = textField.text else { return true }
    let newLength = text.characters.count + string.characters.count - range.length
    return newLength <= 12 // Bool
    
}

When i use .currency method it crashes the app also:

formatter.numberStyle = .currency
Community
  • 1
  • 1
vaibhav
  • 4,038
  • 1
  • 21
  • 51
  • Check this out: http://stackoverflow.com/questions/24960621/struggling-with-nsnumberformatter-in-swift-for-currency – d4Rk Apr 24 '17 at 07:42
  • Add `return false` after `textField.text = formattedNum`. You should also remove all non-integer characters. – Sulthan Apr 24 '17 at 07:47
  • @Sulthan, by adding `return false after textField.text = formattedNum` i wont be able to edit textfield. – vaibhav Apr 24 '17 at 07:51
  • @vaibhav Well, do you understand that if you change the text and then you let the textfield to change the text again, you won't get the desired behavior? – Sulthan Apr 24 '17 at 08:00
  • @Sulthan, sorry didn't get point. – vaibhav Apr 24 '17 at 08:03
  • @vaibhav you want to convert your number into US currency right ? – Himanshu Moradiya Apr 24 '17 at 09:16
  • $8,965,489,896,479,644.00 you want your output like this ? – Himanshu Moradiya Apr 24 '17 at 09:18
  • @HimanshuMoradiya, the ans you delivered which i was already using by sending whole string to apply currency sign and comma, but this time i am separating number using comma while enter in uitextfield see ques again. – vaibhav Apr 24 '17 at 09:29

3 Answers3

2

Here is code

func getNumberWithFormat(_ number : NSNumber, format : String) -> String {
     let numberFormatter = NumberFormatter()
     numberFormatter.locale = Locale.current
     numberFormatter.numberStyle = NumberFormatter.Style.decimal
     numberFormatter.usesGroupingSeparator = true

     numberFormatter.positiveFormat = format
     return numberFormatter.string(from: number)! 
}

You can call this function like,

let number : NSNumber = 300000 
print("Number is : ", getNumberWithFormat(number, format: "###,###"))

Your output will be

Number is :  300,000
0

I think this is due to your locale settings. In some areas of the world, they have number formats like that. I tested your code and it worked fine, so I guess there must be something with wrong with your locale.

If you want the number to be in the US style, just set the locale explicitly:

// here pass your textfield value that you want to convert into doller.

 let price = NSDecimalNumber(string: self.textfield.text) as NSNumber
 let formatter = NumberFormatter()
 formatter.numberStyle = .currency
 formatter.locale = Locale(identifier: "en_US")
 formatter.string(from: price)
 print(formatter.string(from: price)!)

Output:

$8,965.00
Himanshu Moradiya
  • 4,769
  • 4
  • 25
  • 49
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0
import UIKit

open class DecimalFormatter: NumberFormatter {

    public override init() {
        super.init()
        locale = Locale.current
        numberStyle = .decimal
        minimumFractionDigits = 2
        maximumFractionDigits = 2
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override open func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, range rangep: UnsafeMutablePointer<NSRange>?) throws {
        guard obj != nil else { return  }
        let str = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
        obj?.pointee = NSNumber(value: (Double(str) ?? 0.0)/Double(pow(10.0, Double(minimumFractionDigits))))
    }
}


let originString = NSNumber.init(value: 30000)
let result = DecimalFormatter().string(from: originString)

you will get 30,000.00 if u want get 30,000, just change "minimumFractionDigits" to "0"

weikel
  • 164
  • 4