How to input currency format on a text field (from right to left) using Swift?
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)
}
@objc 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.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)!
}
}
SwiftUI input currency format in a text field (from right to left)
I have created a currencyTextField that wraps around a UITextfield. It's not right to left, but you can modify it to be so by removing some cursor code.
Here's the demo
and here's the repo https://github.com/youjinp/SwiftUIKit
Format currency in textfield in Swift on input
I modified the function from earlier today. Works great for "en_US" and "fr_FR". However, for "ja_JP", the division by 100 I do to create decimals is a problem. You will need to have a switch or if/else statement that separates currencies with decimals and those that do not have them when formatted by the formatter. But I think this gets you in the space you wanted to be.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
var currentString = ""
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
}
//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
println(currentString)
formatCurrency(string: currentString)
default:
var array = Array(string)
var currentStringArray = Array(currentString)
if array.count == 0 && currentStringArray.count != 0 {
currentStringArray.removeLast()
currentString = ""
for character in currentStringArray {
currentString += String(character)
}
formatCurrency(string: currentString)
}
}
return false
}
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)/100
textField.text = formatter.stringFromNumber(numberFromField)
println(textField.text )
}
}
How to input currency format on a text field (from right to left) using Swift?
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)
}
@objc 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.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)!
}
}
Trying to format a UITextField to behave like a currency calculator for only numeric input in iOS
Here's a nice way to do it. Remember to set your UITextField to self in the viewDidLoad method and your header file must conform to the UITextFieldDelegate protocol
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *cleanCentString = [[textField.text componentsSeparatedByCharactersInSet: [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
NSInteger centValue = [cleanCentString intValue];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
NSNumber *myNumber = [f numberFromString:cleanCentString];
NSNumber *result;
if([textField.text length] < 16){
if (string.length > 0)
{
centValue = centValue * 10 + [string intValue];
double intermediate = [myNumber doubleValue] * 10 + [[f numberFromString:string] doubleValue];
result = [[NSNumber alloc] initWithDouble:intermediate];
}
else
{
centValue = centValue / 10;
double intermediate = [myNumber doubleValue]/10;
result = [[NSNumber alloc] initWithDouble:intermediate];
}
myNumber = result;
NSLog(@"%ld ++++ %@", (long)centValue, myNumber);
NSNumber *formatedValue;
formatedValue = [[NSNumber alloc] initWithDouble:[myNumber doubleValue]/ 100.0f];
NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
[_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
textField.text = [_currencyFormatter stringFromNumber:formatedValue];
return NO;
}else{
NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
[_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
textField.text = [_currencyFormatter stringFromNumber:00];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Deposit Amount Limit"
message: @"You've exceeded the deposit amount limit. Kindly re-input amount"
delegate: self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK",nil];
[alert show];
return NO;
}
return YES;
}
UITextField display formatted as currency without decimal
Try below code
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text: NSString = (textField.text ?? "") as NSString
let finalString = text.replacingCharacters(in: range, with: string)
// 'currency' is a String extension that doews all the number styling
amountTextField.text = finalString.currency
// returning 'false' so that textfield will not be updated here, instead from styling extension
return false
}
}
extension String {
var currency: String {
// removing all characters from string before formatting
let stringWithoutSymbol = self.replacingOccurrences(of: "$", with: "")
let stringWithoutComma = stringWithoutSymbol.replacingOccurrences(of: ",", with: "")
let styler = NumberFormatter()
styler.minimumFractionDigits = 0
styler.maximumFractionDigits = 0
styler.currencySymbol = "$"
styler.numberStyle = .currency
if let result = NumberFormatter().number(from: stringWithoutComma) {
return styler.string(from: result)!
}
return self
}
}
How to make it so that user enters currency only with numbers in SwiftUI textfield, while preserving the $ and the .?
To create a currency field that allow the user to type an amount from right to left you would need an observable object (binding manager), a currency number formatter and observe every time the value changes using onChange method:
import SwiftUI
struct ContentView: View {
@ObservedObject private var currencyManager = CurrencyManager(amount: 0)
@ObservedObject private var currencyManagerUS = CurrencyManager(
amount: 0,
locale: .init(identifier: "en_US")
)
@ObservedObject private var currencyManagerUK = CurrencyManager(
amount: 0,
locale: .init(identifier: "en_UK")
)
@ObservedObject private var currencyManagerFR = CurrencyManager(
amount: 0,
locale: .init(identifier: "fr_FR")
)
@ObservedObject private var currencyManagerBR = CurrencyManager(
amount: 100,
maximum: 100,
locale: .init(identifier: "pt_BR")
)
var body: some View {
VStack(alignment: .trailing, spacing: 0) {
Spacer()
Group {
Text("Locale currency")
TextField(currencyManager.string, text: $currencyManager.string)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.onChange(of: currencyManager.string, perform: currencyManager.valueChanged)
Spacer()
}
Group {
Text("American currency")
TextField(currencyManagerUS.string, text: $currencyManagerUS.string)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.onChange(of: currencyManagerUS.string, perform: currencyManagerUS.valueChanged)
Spacer()
}
Group {
Text("British currency")
TextField(currencyManagerUK.string, text: $currencyManagerUK.string)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.onChange(of: currencyManagerUK.string, perform: currencyManagerUK.valueChanged)
Spacer()
}
Group {
Text("French currency")
TextField(currencyManagerFR.string, text: $currencyManagerFR.string)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.onChange(of: currencyManagerFR.string, perform: currencyManagerFR.valueChanged)
Spacer()
}
Group {
Text("Brazilian currency")
TextField(currencyManagerBR.string, text: $currencyManagerBR.string)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.onChange(of: currencyManagerBR.string, perform: currencyManagerBR.valueChanged)
}
Spacer()
}.padding(.trailing, 25)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class CurrencyManager: ObservableObject {
@Published var string: String = ""
private var amount: Decimal = .zero
private let formatter = NumberFormatter(numberStyle: .currency)
private var maximum: Decimal = 999_999_999.99
private var lastValue: String = ""
init(amount: Decimal, maximum: Decimal = 999_999_999.99, locale: Locale = .current) {
formatter.locale = locale
self.string = formatter.string(for: amount) ?? "$0.00"
self.lastValue = string
self.amount = amount
self.maximum = maximum
}
func valueChanged(_ value: String) {
let newValue = (value.decimal ?? .zero) / pow(10, formatter.maximumFractionDigits)
if newValue > maximum {
string = lastValue
} else {
string = formatter.string(for: newValue) ?? "$0.00"
lastValue = string
}
}
}
extension NumberFormatter {
convenience init(numberStyle: Style, locale: Locale = .current) {
self.init()
self.locale = locale
self.numberStyle = numberStyle
}
}
extension Character {
var isDigit: Bool { "0"..."9" ~= self }
}
extension LosslessStringConvertible {
var string: String { .init(self) }
}
extension StringProtocol where Self: RangeReplaceableCollection {
var digits: Self { filter (\.isDigit) }
var decimal: Decimal? { Decimal(string: digits.string) }
}
This is the SwiftUI equivalent to the custom CurrencyField I have implemented for UIKit.
Related Topics
Redirect to Application If Installed, Otherwise to App Store
React Native App Works on Debug Mode, But Not Works Release Mode on Ios
How to Export Uiimage Array as a Movie
How to Present Uialertcontroller When Not in a View Controller
How to Easily Resize/Optimize an Image Size With Ios
How to Convert String Date to Nsdate
Background Location Services Not Working in iOS 7
How to Convert a Uiview to an Image
How to Change Navigation Bar Color in iOS 7
How to Access a Specific Field from Cloud Firestore Firebase in Swift
Disabling Auto-Play in Full Screen on Ios
What's the Difference Between the Atomic and Nonatomic Attributes
How to Input Currency Format on a Text Field (From Right to Left) Using Swift