I've been tearing my hair out trying to find a solution to this.
I simply want a UITextField to correctly format an inputted number as a price. That means only a single decimal point is allowed, two digits after the point (if they were typed in) and a ',' to separate large numbers (eg 150,000).
That is how a price is properly format开发者_运维百科ted, so why is it so difficult to get right?
The closest I've come to a solution is this code. The problem with it, however, is after typing in four digits it reverts to 0?? This is close to a solution, I just can't understand why it does this strange behavior.
You actually don't need any code for this. Just drag a number formatter on your text field in the nib file and configure it to use the "Currency" style.
Via code this would be [myNumberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]
Beware that the format of prices is very different depending on the locale. In Germany for example, the dot is used as a thousands separator and the comma as the decimal point. Using a style instead of a fixed format takes care of those differences for you.
Hi Here is my solution.
import UIKit
extension Numeric { // for Swift 3 use FloatingPoint or Int
func currency(locale: String, symbol: Bool = true) -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: locale)
if !symbol {
formatter.currencySymbol = ""
}
let result = formatter.string(for: self) ?? ""
return result
}
}
ViewController Code
var price: String!
var priceNumber: CGFloat!
@IBOutlet weak var priceInput: UITextField!
ViewDidLoad
priceInput.addTarget(self, action: #selector(priceInputChanged), for: .editingChanged)
priceInput.tintColor = .clear
priceInput.delegate = self
UITextFieldDelegate in Your ViewController
@objc func priceInputChanged(_ textField: UITextField){
if localIdentifier != nil {
priceInput.text = priceNumber.currency(locale: localIdentifier, symbol: false)
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.tag == 3 {
if string.isEmpty {
if price.count > 0 {
let last = price.removeLast()
if last == "." {
if price.count > 0 {
price.removeLast()
}
}
}
}else {
price.append(string)
}
if let input = price {
let n = NumberFormatter().number(from: input) ?? 0
priceNumber = CGFloat(truncating: n)
if localIdentifier != nil {
priceInput.text = priceNumber.currency(locale: localIdentifier, symbol: false)
}
}
}
return true
}
That's It
精彩评论