Eureka
Eureka copied to clipboard
Yet another NumberFormatter/DecimalFormatter with DecimalRow problem
Desired behavior:
On empty form there should be a place holder on the row. Ideally, the user can delete the contents and see the placeholder again. The user should be able to enter a decimal formatted number of their choice. 125, 125.5 125.567 should all be acceptable. Ideally, it would not adjust their entry in any way. However, rounding to 2 decimal places would not be the end of the world.
Actual Behavior 1 (the closest to sanity I can get currently):
let formatter = DecimalFormatter()
row.title = "Label:"
row.placeholder = "Enter Number"
row.useFormatterOnDidBeginEditing = true
row.useFormatterDuringInput = true
row.formatter = formatter
row.add(rule: RuleRequired())
row.validationOptions = .validatesOnChange
This starts with a placeholder (by setting initial row.value to nil). So that's good. When you type 1, it converts it to 0.01. Then you keep typing the rest of your numbers and you can get a reasonable result. The number always has 2 decimal places: 125.50
Not having to type the decimal is neat, but honestly probably confusing for my users. I would rather let them type what they want. Now, I delete all the numbers and I am left with: 0.00 (not my placeholder).
This at least works. (and what I may be stuck with at the moment)
Actual Behavior 2:
So, I disable useFormatterDuringInput. The idea being that the user can type what they want.
This almost works as long as the user always types 2 number to the right of the decimal point. If you type 125.5 you get converted to 12.5 when you leave the field.
Actual Behavior 3:
I set formatter.minimumFractionDigits = 0
This forces all entered numbers to have no decimal point. If you enter 12.5 you get 125 when you exit the field. I would have thought this would allow no decimal point, not force you not to have them.
With minimumFractionDigits set, maximumFractionDigits seems to be meaningless.
So, I move on to NumberFormatter instead.
Actual Behavior 4:
I use the same setup as behavior 1. The textfield will not let me type a period. Period.
Actual Behavior 5:
So I set row.useFormatterDuringInput = false.
This one gets really close. Everything works except if the user deletes all the content (placeholder appears) and then types a number. Instead of just having that number it appends a .0 to it. Now the user has to remove the .0 and type what they want.
Strangely, this does not happen on initial entry of a blank field. Only after the user deletes and enters. (I do set row.value to nil initially)
I have tried many many more combinations. But I have found very few that actually produce logically useable results.
I would love to see how people are using this without creating a poor UX experience.
Thoughts on fixing this:
Create Numeric Rules that work on plain string value TextRow. In this way, making the text be a number is a matter of validation instead of formatting. TextRow can easily use various numeric keypads to help. (I am looking at adding my own rules to try this)
DecimalFormatter seems to ignore many of the NumberFormatter attributes. I don't understand why that is. But fixing that may enable more useable scenarios.
Anyway, I am still trying to get something other than Behavior 1.
I have the same problem. It's really annoying