views:

76

answers:

2

I have an instance of NSTextField, e.g. someTextField, for which I will use the number formatter to limit the input to numbers only.

The problem comes with the localization combined with the specific keyboard layouts used.

I would like to allow both the, say, american and european users to enter their localized decimal separators. As you all know it, in the USA that would be . and for the good part of Europe that would be , (and similar is with the thousands separator, etc. but let's put that to the side for now).

So I wrote the following task: [numberFormatter setLocale:[NSLocale currentLocale]]; for the instance of the NSNumberFormatter.

Problems occurs when user who has , set as a decimal separator AND US keyboard layout switched on (case fairly often here in Europe) presses the decimal separator key on the numeric keyboard. With the US kyboard layout on, that would give him the . as the decimal separator but at the same time it'll be ignored in the someTextField because of the localized settings system-wide. So, if you want to type 1/2 using numeric keyboard only, you'll type 0.5 (US keyboard layout) in the text field and it would be read by the system as 0 because it recognizes only , as decimal separator. This is how the program currently is working and I would like to improve it in this regard.

I would like to allow user to type in the . in the someTextField and for the system to recognize it as a decimal separator just like it would ,. This kind of behavior can be seen in Apple's own Calculator application. If you type . on the numeric keyboard it'll appear as , immediately on the screen (for all conditions as described previously).

Question is: is it possible for me to achieve this using an instance of NSNumberFormatter? If not, is it possible to set on-the-fly conversion of the numerical keyboard decimal separator key output to the decimal separator set system-wide? Or perhaps you have some other suggestions?

Thanks.

A: 

I don't have a specific answer to your question, but I'd say the right approach is not to muck about with the NSNumberFormatter at all and concentrate on trying to change the characters generated by the keyboard.

The default locale for number formatters is usually the system's default locale as set by the user in the internationalization settings. If you change that behaviour programmatically for UI elements, you are effectively telling the user "I know better than you how you want to input numbers". Arrogance of that sort on the part of the developer never gets them good marks with respect to UI design.

In fact, you could apply the same argument to remapping the dot button on the numeric keypad. How do you know that the user hasn't set US keyboard layout because it allows them to get a dot from that key? Maybe they consider it more important to be able to type the thousands separator from the keypad than the decimal separator. I'm not saying you shouldn't implement your feature, just make sure that the user has control over when it is enabled or disabled.

Anyway, you probably want to override the keyDown event on the control. More info here.

JeremyP
Thank you for the reply and the links. I have absolutely no intention on enforcing my way of doing things on the users. On the contrary - I'm just thinking about reducing their effort. I mentioned Apple's Calculator - many of my coleagues (and me too) do preffer the ability to keep the hand on the numeric keyboard and keep typing decimal numbers instead moving the hand to the `,` key or, worse, switching the layouts. I'll have to check the Apple Calculator behavior regarding the thousand separators though, as I do think you have the point there.
Miloš
A: 

Take a look at the UITextFieldDelegate protocol. It allows your textfield to ask its delegate if it should accept a character which the user just typed. The apropriate method would be textField:shouldChangeCharactersInRange:replacementString. If the character in question is , or . just let the delegate append the properly localized decimal separator "manually" and return NO.

I'm not quite sure if this will work if the text field is set to number mode, maybe the input is being filtered before the delegate method is called - leading to the method not being called if the "wrong" separator has been filtered out previously. If so, you might want to consider leaving the text field in alphanumerical mode and use the delegate method again to filter out anything that is not numbers or separators. However, in this case you should make sure the user is not allowed to type more then one decimal separator - either ignore the surplus ones or remove the first one and accept the new one.

Toastor