How can I limit the number of decimal points in a UITextField?

后端 未结 15 2252
说谎
说谎 2020-12-01 05:20

I have a UITextField that when clicked brings up a number pad with a decimal point in the bottom left. I am trying to limit the field so that a user can only place 1 decimal

相关标签:
15条回答
  • 2020-12-01 06:03

    Implement the shouldChangeCharactersInRange method like this:

    // Only allow one decimal point
    // Example assumes ARC - Implement proper memory management if not using.
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
    {
        NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
        NSArray  *arrayOfString = [newString componentsSeparatedByString:@"."];
    
        if ([arrayOfString count] > 2 ) 
            return NO;
    
        return YES;
    }
    

    This creates an array of strings split by the decimal point, so if there is more than one decimal point we will have at least 3 elements in the array.

    0 讨论(0)
  • 2020-12-01 06:04

    Here is an example with a regular expression, the example limits to only one decimal point and 2 decimals. You can tweak it to fit your needs.

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
        NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
        NSString *expression = @"^[0-9]*((\\.|,)[0-9]{0,2})?$";
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error];
        NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString options:0 range:NSMakeRange(0, [newString length])];
        return numberOfMatches != 0;
    }
    
    0 讨论(0)
  • 2020-12-01 06:04

    In whatever object you set your UITextField's delegate to, add a method that answers to "[- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string]".

    Then you can either use a NSNumberFormatter object or you can brute force check for an already existing decimal place mark (returning NO if a decimal mark already exists).

    0 讨论(0)
  • 2020-12-01 06:05

    I made the solution, that brings you control over decimal places count, so user can type only one decimal separator and you can also have a control over decimal places count.

    Just set the decimalPlacesLimit value properly.

    See the method:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        NSLog(@"text on the way: %@", string);
        NSUInteger decimalPlacesLimit = 2;
    
        NSRange rangeDot = [textField.text rangeOfString:@"." options:NSCaseInsensitiveSearch];
        NSRange rangeComma = [textField.text rangeOfString:@"," options:NSCaseInsensitiveSearch];
        if (rangeDot.length > 0 || rangeComma.length > 0){
            if([string isEqualToString:@"."]) {
                NSLog(@"textField already contains a separator");
                return NO;
            } else {
                NSArray *explodedString = [textField.text componentsSeparatedByString:@"."];
                NSString *decimalPart = explodedString[1];
                if (decimalPart.length >= decimalPlacesLimit && ![string isEqualToString:@""]) {
                    NSLog(@"textField already contains %d decimal places", decimalPlacesLimit);
                    return NO;
                }
            }
        }
    
        return YES;
    }
    
    0 讨论(0)
  • 2020-12-01 06:07
    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
        if([string isEqualToString:@"."]) {
            BOOL containsDecimal = [textField.text containsString:@"."];
            return !containsDecimal;
        }
        return YES;
    }
    

    If textfield text already contains a '.' then return NO else return YES.

    0 讨论(0)
  • 2020-12-01 06:08

    Swift 4

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        // Allow to remove character (Backspace)
        if string == "" {
            return true
        }
    
       // Block multiple dot
        if (textField.text?.contains("."))! && string == "." {
            return false
        }
    
        // Check here decimal places
        if (textField.text?.contains("."))! {
            let limitDecimalPlace = 2
            let decimalPlace = textField.text?.components(separatedBy: ".").last
            if (decimalPlace?.count)! < limitDecimalPlace {
                return true
            }
            else {
                return false
            }
        }
        return true
    }
    

    Objective-C

    //Create this variable in .h file or .m file
    float _numberOfDecimal;
    
    //assign value in viewDidLoad method
    numberOfDecimal = 2;
    
    #pragma mark - TextFieldDelegate
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
        // Allow to remove character (Backspace)
        if ([string isEqualToString:@""]) {
            return true;
        }
    
        // Block multiple dot
        if ([textField.text containsString:@"."] && [string isEqualToString:@"."]) {
            return false;
        }
    
        // Check here decimal places
        if ([textField.text containsString:@"."]) {
            NSString *strDecimalPlace = [[textField.text componentsSeparatedByString:@"."] lastObject];
    
            if (strDecimalPlace.length < _numberOfDecimal) {
                return true;
            }
            else {
                return false;
            }
        }
        return true;
    }
    
    0 讨论(0)
提交回复
热议问题