Simple Formatting in a Cocoa Touch Text Edit Field (UITextField)

Simple Formatting in a Cocoa Touch Text Edit Field (UITextField)

Several challenges of the XCode / Cocoa Touch development environment involve doing things that are trivial in other places, but no so much so within XCode.

One of those challenges is formatting a text edit field.  Social security numbers, phone numbers, postal codes, VINs… the kind of mundane crap that is uber-trivial in tools like MS Access, but often prove to be ball-busting-ly frustrating to do in Objective-C.

For me particularly, I had a price field that I wanted to display.

Apple supplies a couple of keyboard choices for the iPhone that could have done the trick for supplying numeric data entry, but they had about 40 characters more than I needed (0-9, and decimal point were all I really desired, and being lazy, didn’t want to write a regular expression for parsing).

There is a phone number pad (no good) and a number pad (almost what I need – but no decimal point).  But the number pad would be “good enough” if I could just embed an implied decimal point.

Apple has no built in / native way to format a text field with say an embedded decimal (so I wouldn’t have to type it). I had to write my own handler to take care of this.

Here is my home brewed work around for this situation. I’m not going to focus on setting up UITextField events, only on the problem at hand.

Consider the following Edit Changed code:

// Our price changed... we want to format it with an implied decimal point.
-(void)textFieldPriceDidChange:(id)textField {

static BOOL toggle = NO;
if (toggle) {
toggle = NO;
return;
}

NSString* strPrice = [[textField object] text];

strPrice = [strPrice stringByReplacingOccurrencesOfString:@"." withString:@""];
toggle = YES;
price.text = [@"" stringByAppendingFormat:@"%0.2f", [strPrice floatValue]/100.0];

}

The code assumes that I have a UITextField named price somewhere on a form. When the field’s text is changed, the event fires, and I:

-) Strip out any existing decimal point,
-) Divide the float representation of the value by 100, to give an implied 2 decimal point precision,
-) Use the printf-styled %0.2f formatting string to pretty up the output the way I want,
-) Put the value back in the field.

But wait a minute… won’t putting a value back into the price field trigger yet another Edit Change event, and cause an endless loop?

Yes. It will.

But take a look at the BOOL static toggle.

That toggle essentially says “OK. If I see that I am already handling the formatting of this field, reset the toggle, and return.”

This is a simple but very effective way to add formatting to a text edit field, and the concept can easily be extended to other formats without a lot of sweat (%05d-%04d, %3d-%2d-%4d, %2d-%7d, %2d/%2d/%4d – you get the point).

Enjoy… and happy coding.

Advertisements

8 thoughts on “Simple Formatting in a Cocoa Touch Text Edit Field (UITextField)

  1. Hi David,

    Thanks for the awesome snippet! I’ve been trying to get it working with in first iphone app. It has 1 text field, 1 label and 1 button and I’d like to know if you would give me some pointer in incorporating that into my app. Thanks!

    Like

  2. Perfect. I have one thing to add that can make your code a bit more international. Although, I wonder how it works with Yen, which doesn’t have a decimal number

    NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
    [currencyStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];

    NSNumber *newNumber = [NSNumber numberWithFloat:[strPrice floatValue]/100.0];
    amountEntered.text = [NSString stringWithFormat:@”%@”,[currencyStyle stringFromNumber:newNumber]];

    Like

  3. Nope, it makes it more of a pain. I had to enter removing “$” and “,” from the string, and in some other locales, would have different symbols, and I got to the point where I had diminished returns

    Like

  4. I’ve been working on a similar formatting issue with phone numbers. The problem that occurs, and that looks like it would also occur with your solution, which is similar to mine, is that if the user thumbs over the text to, for instance, change one of the characters that’s not at the end of the string, when the text is replaced, the cursor will move to the end of the string in the textfield. It’s really frustrating if you’re trying to change a few characters in the middle of a string. I’d love to know how apple or loopt do it in the contacts and registration respectively.

    Like

  5. I have also been working on the similar formatting issue with decimal numbers. I need to enter a decimal number in a field. Since Apple does not provide DOT (.) with number pad, a DOT is imbed in the number pad i used. The problem that occurs is a DOT can be repeatedly entered in the field more than once while a DOT once entered must not be entered again as it makes the number invalid. All suggestions are welcome!

    Like

  6. You can make it work like a calculator display by creating a hidden text field and intercepting changes to it (Remember to make this field the first responder). Then you apply your formatting to the text displayed in the visible field whenever the text in the hidden field changes (Remember to disable user interaction for the visible field). Since the hidden field will only contain numeric text, you can easily format the text in the visible field using any number formatter you want without having to know what to strip out. The downside of this approach is that the user must hit the back button to delete values. However, users have fairly consistent expectations about number fields when displayed using a calculator-like look and feel.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s