Create a Subclass of UITextField in Swift to Support Currency Input

Josh Rondestvedt
The Startup
Published in
4 min readOct 4, 2020

--

https://unsplash.com/photos/ZVprbBmT8QA

Creating a UITextField to handle currency input might seem easy enough until you actually start writing the code. The first issue you will probably come across is how are you going to restrict the user from entering anything other than numbers. Then you might realize that forcing users to enter periods and commas isn’t the best user experience. Here are some additional issues you will run into:

  • Not all regions and countries have their currency symbol on the left like in the United States.
  • Some regions and countries switch the placement of commas and periods.
  • Some currencies are formatted as whole numbers instead of two decimal places (ie. Japanese Yen JPY).
  • If you want to save the entered currency to your database as a number (Double, Float, etc), you will “clean” the currency string so your app doesn’t crash when you try to use the amount in a calculation.

At the time of writing, Swift has 903 locale and currency code combinations to select from. You can retrieve all these by looping through Locale.availableIdentifiers.

Like I alluded to at the beginning, there are more things you need to consider than originally thought.

Lets get started

Please note — this article isn’t intended to teach you everything you need to know about working with currencies in Swift. My hope is you will see my UITextField subclass and be able to come away with some conclusions of your own. With that being said, let’s go.

By the end of this article, here is what your text field will produce:

As you can see, entering “1” into the text field will be formatted as “$0.01”, entering “2” will be formatted as “$0.12”, and so on. In my opinion, this is the best user experience. This way, the user doesn’t have to worry about entering the currency symbol, making sure they have the period in the right place, etc. All they have to do is type the numbers.

I know, that’s a lot to take in. I am not going to explain every line of code but I will try to explain the key ingredients. To see the contents of the Currency type, please see the entire project on Github.

  1. This closure/callback will pass the formatted currency string and the “clean” numerical amount to your UIViewController, ViewModel, etc. every time the user changes the textField contents.
  2. When you create the instance of the CurrencyTextField in your UIViewController, you will want to pass a currency instance so the text field has the locale, currencyCode, etc.
  3. Here is the CurrencyTextField’s number formatter marked as private since only this class needs access to it.
  4. Remember how I said some currencies are formatted as whole numbers (ie. JPY)? The computed property will either return 2 or 0 depending on the currency requested. This is also a key part of this text field because it determines if the entered amount needs to be divided by 100.
  5. This private property assists the shouldChangeCharactersIn range delegate method in determining if the currency symbol is on the right or left. This is key when the user hits the delete button and the currency is on the right.
  6. This method sets up the text field including setting the keyboard type to numberPad. This restricts the user from entering in letters instead of numbers.
  7. This method is called every time a use changes the contents of the text field. This method loops through the characters of the entered string and removes all characters that are not numeric. After the entered amount is “cleaned”, the class determines if the currency is formatted as a whole number (ie. JPY) or with two decimals places (ie. USD). After this, both the formatted string amount and the cleaned value are passed back to the ViewController by the passTextFieldText callback.
  8. I found this method on Stack Overflow to ensure the cursor always starts at the far right of the text field and disables the ability to move it around.
  9. Last but not least, this UITextField delegate method detects the single character the user entered as well as the string that was in the text field before the change. I use this method to determine if the user has hit the back button and if the currency symbol is on the right-hand side of the text field text.

Adding to the ViewController

Here is a basic implementation on how to add it to a UIViewController. Notice — no need to conform to the UITextFieldDelegate protocol methods. All logic is contained in the custom UITextField subclass. The great thing about this is the formatted string amount and the cleaned Double amount are passed back in the passTextFieldText callback.

Note — you can also use this if you are using Storyboards.

Wrap Up

If you have worked with currency formatting in the past, I hope you can appreciate the simplicity of this approach. My goal was to make this as straight forward as possible and not get too technical.

Feel free to get the entire project from GitHub. This project will also help you see how other currencies are formatted in their specific locale.

--

--

Josh Rondestvedt
The Startup

Software Developer at Branch. Founder of the iOS app seventytwo. I build cool software for Apple devices.