views:

806

answers:

5

I'm writing an iPhone app that has a textField for the user to enter a "dollar amount" like 12.34

None of the SDK keyboards seem to have a decimal point. (OR do they?) So I decided to just let the user type in "1234" and I would add the decimal point for him... as he types.... by using EDITING CHANGED.

But each time my code adds the decimal point... it generates ANOTHER "EDITING CHANGED" event... and causes an endless loop.

Or is there an easier way to do all of the above?

A: 
  1. Make your own view as a keyboard (recommended), or
  2. Just use the numbers & punctuation keyboard and put in validation, or
  3. Separate the "dollars" and "cents" text fields (not recommended).
KennyTM
1. Wow. Really? 12 more buttons... 12 more outlets... 12 more connections... 12 more releases... and the code? ___________________________ 2. Keys are far too small. ___________________________ 3. Messy So there really is no "easy way", is there?
Donna
You can use the NumPad keyboard and put a "decimal point" button on top of the keyboard but I guess that will involve accessing undocumented view hierarchy.
KennyTM
A: 

You can change the UITextField's text during delegate's textField:shouldChangeCharactersInRange:replacementString: - just return NO from this method, but change the text (add the decimal point), like this:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];

    // add decimal point to newText

    textField.text = newText;
    return NO;
}

Alternatively, use a static BOOL in your value changed handler to indicate you're changing the value by yourself, somethign like:

-valueDidChange:(id)notify {
     static BOOL ownChange = NO;
     if (ownChange) return;
     ownChange = YES;
     textField.text = "12.23";
     ownChange = NO;
}

This is not pretty, though :)

Adam Woś
+3  A: 

Please post your request as a bug in the iPhone Developer Portal. Apple will not add a new keyboard type that is simply numbers with the decimal separator until they hear from a large number of developers who need one...

-t

Tim
+1  A: 

You can add custom buttons to an existing keyboard. I've done this to add a "Done" button to the numeric keyboard. Why not add others? You could cut the delete key in half and add a half size key for a decimal point. Anyway, here's the code:

    - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
        if ( MAKE SURE THIS IS BEING CALLED BY THE CORRECT TEXT FIELD ) {

           // locate keyboard view
           UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
           UIView* keyboard;

           for(int i = 0; i < [tempWindow.subviews count]; i++) {
                  keyboard = [tempWindow.subviews objectAtIndex:i];
                  // keyboard view found; add the custom button to it
                  if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
                         [keyboard addSubview:doneButton];
           }
        }
        else
           [doneButton removeFromSuperview];
    }  

You need to create a UIButton from an image so it looks like a key. Use the above function to add it to the keyboard whenever it's called up. Actually works quite well.

Combat
Your codes hold the button or created in xib. The only concern is that if the keyboard layout or style is changed, then your button may be ugly.
David.Chu.ca
I used your method and it has worked until iOS4...It seems that [[UIApplication sharedApplication] windows] has now only one element.Do you have any idea to solve this issue?
Geraud.ch
For iOs4, you should have a look at: http://www.neoos.ch/news/46-development/54-uikeyboardtypenumberpad-and-the-missing-return-key:)
Geraud.ch
A: 

It isn't perfect as it is at the top of the keyboard, but you can add a button in an inputAccessoryView (documented and legit). I define a toolbar in the xib file (not in my main view) with touch-up mapped to a method that adds the decimal to the field. I assign it in doLoad:

    descriptionTextArea.inputAccessoryView = editorControlView;
Peter DeWeese