I want to give my textfield a Currency format so when I type it looks like:
$0.00
$0.09
$0.98
$9.87
$98.76
So what I did was:
An extension of ObservableType
with 2 functions, one for transform into the desired format and other to read the value:
extension ObservableType where E == String {
func currencyFormattedToValue() -> Observable<E> {
return asObservable().flatMap { currencyString -> Observable<E> in
let formatter = Constants.moneyFormatter
let value = Double(truncating: formatter.number(from: currencyString) ?? 0.00).rounded(toPlaces: 2)
return Observable.just("\(value)")
}
}
func valueToCurrencyFormatted() -> Observable<E> {
return asObservable().flatMap { valueString -> Observable<E> in
let formatter = Constants.moneyFormatter
var amountWithPrefix = valueString
var number: NSNumber!
let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, valueString.count), withTemplate: "")
let double = (amountWithPrefix as NSString).doubleValue
number = NSNumber(value: (double / 100))
guard number != 0 as NSNumber else {
return Observable.just("$0.00")
}
return Observable.just(formatter.string(from: number)!)
}
}
}
And then I used them like so:
textField.rx.text
.orEmpty
.changed
.valueToCurrencyFormatted()
.bind(to: self.textField.rx.text)
.disposed(by: disposeBag)
and to read the value and bind it to a subject:
textField.rx.text
.orEmpty
.currencyFormattedToValue()
.bind(to: viewModel.amountValue)
.disposed(by: disposeBag)
My Formatter:
class Constants {
static var moneyFormatter:NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = "$"
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
return formatter
}
}
I'm open tu suggestions, thanks!