nico9T
nico9T

Reputation: 2716

Custom UITextField with max decimal numbers

I would like to create a custom UITextField with:

1) Only one decimal point allowed. 2) A max number of decimals the user can enter (will be a property), let's say 2.

What would be my best to accomplish this?

I created a new class that inherits from UITextField.

For the point #1 I found on stackoverflow I should rely on the following method:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Implementing it like this:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

  NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

  NSArray *sep = [newString componentsSeparatedByString:@"."];
  if([sep count]>=2)
  {
    NSString *sepStr=[NSString stringWithFormat:@"%@",[sep objectAtIndex:1]];
    return !([sepStr length]>1);
  }
  return YES;
}

The first problem is that this is a method of the UITextField delegate, not available for my new object that inherits from UITextField. I would like my custom UITextField to implement it by default but there is not such method.

The second problem is that the decimal separator could be "." or ",". Is there a way to find what is the decimal separator for the pad?

For the point #2, the max number of decimas a user can enter, I guess I'd check if there are already 2 digits after the decimal separator, if so I won't modify the UItextField.text.

Thanks

Nicola

Upvotes: 0

Views: 486

Answers (1)

StaRbUck42
StaRbUck42

Reputation: 117

Implement the UITextFieldDelegate methods in your custom UITextField as normal.

Then you can create a proxy for the delegate that refers outside callers to the delegate as set by the ViewController

override the @property id<UITextfieldDelegate> to return the delegate set by the ViewController.

As implemented in your UITextField subclass:

(id) init {
   self = [super init];
   if (self) {
      //register ourselves as the delegate with UITextField
      super.delegate = self;
      //custom initialization code
   }
   return self;
}

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

  NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

  NSArray *sep = [newString componentsSeparatedByString:@"."];
  if([sep count]>=2)
  {
    NSString *sepStr=[NSString stringWithFormat:@"%@",[sep objectAtIndex:1]];
    BOOL ret = !([sepStr length]>1);
    if(ret)
       return [_delegate textfield:textField shouldChangeCharactersInRange:range replacementString:string];
    return return NO;
  }
  return [_delegate textfield:textField shouldChangeCharactersInRange:range replacementString:string];
}

Basically, make sure you forward the delegate methods to the ViewController if they should have a say in it. (For shouldChangeCharactersInRange:, the ViewController delegate only gets a say if it's okay to change the text )

protip: when you forward the delegate methods, make sure they implement them by checking with respondsToSelector:, and make sure that the delegate is non nil.

Upvotes: 0

Related Questions