0

I am using following textfield delegate to validate user entry.

Lets assume that currentTotal equals 30.00 dollars and whenever user enters two times equal or bigger than currentTotal and I am trying to issue an alert.

While I am testing the application, when user enters 63 dollars, no alert happens, but as long as user enters 630 dollars then alert is issued.

tip and currentTotal are double.

What am I doing wrong, any suggestions?

- (BOOL)textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{    
    if ([aTextField.text containsString:@"$"])
    {
        tip = [[aTextField.text stringByReplacingOccurrencesOfString:@"$" withString:@""] doubleValue];
    }
    else
    {
        tip = [aTextField.text doubleValue];
    }

    if(tip > currentTotal *2)
    {
      [self presentViewController:[AppConstant oneButtonDisplayAlert:@"Error" withMessage:@"Please enter valid tip"] animated:YES completion:nil];
    }

    return YES;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    self.tipTF.text = @"$ ";
}
casillas
  • 16,351
  • 19
  • 115
  • 215
  • whats your currentTotal – Anbu.Karthik Jul 25 '17 at 04:38
  • It is 30.00, double. – casillas Jul 25 '17 at 04:39
  • convert double to integerValue and check once – Anbu.Karthik Jul 25 '17 at 04:39
  • I need to keep double. When I am debugging, even though on the text field I see `63`, but in the delegate method I see `tip` value is `6`. When I add one more digit to make it `630`, then I see tip value is `63` and then it issues an alert. – casillas Jul 25 '17 at 04:40
  • see this https://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield – Anbu.Karthik Jul 25 '17 at 04:43
  • Could you please specify the issue on my implementation? – casillas Jul 25 '17 at 04:48
  • sure give 2 minutes – Anbu.Karthik Jul 25 '17 at 04:48
  • Please show the code to set `currentTotal` and where it is located. – Amin Negm-Awad Jul 25 '17 at 05:06
  • `currentTotal = 30.00` is hardcoded at the moment in the `viewDidLoad`. – casillas Jul 25 '17 at 05:08
  • You seem to be missing the fact that `shouldChangeCharactersInRange` is called *before* the text is changed. You are checking the value before the update is made. Use your debugger and step through the code. And why, based on my answer to your last question, are you hardcoding a `$` symbol instead of using a `NumberFormatter` to properly parse and format currency values entered by the user? – rmaddy Jul 25 '17 at 06:41
  • I am using `NumberFormatter` instead. Based on your comment, this delegate is getting called before it updates the `texfield` that makes sense based on when the value of the `textfield` when I was debugging. Therefore, I wonder what delegate is appropriate to handle this issue. – casillas Jul 25 '17 at 15:16
  • check this one https://stackoverflow.com/questions/7010547/uitextfield-text-change-event – casillas Jul 27 '17 at 04:55

2 Answers2

3

The method you use is -textView:shouldChangeCharactersInRange:replacement. The should means that the action is on to be done, but not be done yet. Therefore getting the value from the text field, you will get the old value.

If you want to know the new value, you have to replace the replacement in your method yourself (make a copy of the string value).

NSString *newValue = [aTextField.text stringByReplacingCharactersInRange:range withString:string];
double tip = [newValue doubleValue]; // Where does your var tip comes from?
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
1
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.tipTF)
    {
        if (self.tipTF.text && self.tipTF.text.length > 0) {
            [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        }
    }
    return YES;
}

-(void)textFieldDidChange :(UITextField *)theTextField{
    NSLog( @"text changed: %@", theTextField.text);
    double tip;
    if ([theTextField.text containsString:@"$"])
    {
        tip = [[theTextField.text stringByReplacingOccurrencesOfString:@"$" withString:@""] doubleValue];
    }else {
        tip = [theTextField.text doubleValue];
    }

    if (tip > currentTotal *2) {
        [self presentViewController:[AppConstant oneButtonDisplayAlert:@"Error" withMessage:@"Please enter valid tip"] animated:YES completion:nil];
    }

}
Megha_Singh
  • 100
  • 4
  • Do not setup the `UIControlEventEditingChanged` event in the `shouldChangeCharactersInRange` delegate method. That's just wrong. Why would your keep calling `addTarget` every time the text field's value is about to change? – rmaddy Jul 25 '17 at 15:55
  • @rmaddy, then what do you suggest? The proposed solution works `textFieldDidChange` is getting called. – casillas Jul 27 '17 at 04:33
  • Setup the text field once in viewDidLoad. – rmaddy Jul 27 '17 at 05:00