How to Test Character Input to UITextField as the User Enters Characters and Prevent Invalid Characters

前端 未结 6 1928
深忆病人
深忆病人 2020-12-02 16:22

First, I setup up the keyboard for the UITextField to use the number with decimal style. So the user can only enter numbers and a single decimal.

What I want to do i

6条回答
  •  一个人的身影
    2020-12-02 16:55

    After much experimentation and looking at other's solutions (which seem to be overly complex and fiddly) I came up with the following, which prevents the user from entering anything but a valid currency amount. Basically, let an instance of NSNumberFormatter (created elsewhere in the viewController) do the hard work:

    • 1) convert the text to a number (if nil, then there are invalid characters, so return NO)
    • 2) then convert the number to currency
    • 3) then convert the currency string back to number and, if different to the original (means too many decimals entered), return NO
    • 4) then make an NSDecimalNumber, which is what I wanted. May be different for you, of course. Works for me so far - hope that this helps someone.

    Firstly, I set the keyboard to UIKeyboardTypeDecimalPad. Then I used the following code

      -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    
    NSString *textString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    NSNumber *amountNumber = [numberFormatter numberFromString:textString];
    
    if ([textString length] > 0) {
        if (!amountNumber) {
            return NO;
        }
    } else {
        amountNumber = @0;
    }
    
    
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    NSString *amountStringer = [numberFormatter stringFromNumber:amountNumber];
    NSNumber *amountAgain = [numberFormatter numberFromString:amountStringer];
    
    //
    //make sure that the number obtained again is the same....prevents too many decimals....
    if (![amountNumber isEqualToNumber:amountAgain]) {
        return NO;
    }
    
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    amountShow.text = amountStringer;
    
    self.amount = [NSDecimalNumber decimalNumberWithDecimal:[amountAgain decimalValue]];
    NSLog(@"decimal Amount is %@", self.amount);
    
    return YES;
    

    }

提交回复
热议问题