如何限制UITextField中的小数点数?

use*_*180 27 decimal-point uitextfield ios

我有一个UITextField,当点击时会在左下角显示一个带小数点的数字键盘.我试图限制该字段,以便用户只能放置1个小数点

例如
2.5 OK
2..5不行

lna*_*ger 43

像这样实现shouldChangeCharactersInRange方法:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

这会创建一个由小数点分割的字符串数组,因此如果有多个小数点,则数组中至少有3个元素.

  • 代替 @"." 对于小数分隔符,也可以从[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]]获取它.这样,代码也可以使用逗号作为分隔符正确地用于区域. (9认同)

niz*_*izx 14

下面是一个带正则表达式的示例,示例仅限于一个小数点和2个小数.您可以调整它以满足您的需求.

- (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;
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.作为建设性的批评者,我建议您提高您的RegEx知识.比如"([0-9] +)?" 可以用"[0-9]*"代替它使它更具可读性和更高性能.我已经对答案进行了适当的改进. (2认同)

Mir*_*vik 8

Swift 3实现此 UITextFieldDelegate 方法以防止用户输入无效数字:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = (textField.text ?? "") as NSString
    let newText = text.replacingCharacters(in: range, with: string)
    if let regex = try? NSRegularExpression(pattern: "^[0-9]*((\\.|,)[0-9]*)?$", options: .caseInsensitive) {
        return regex.numberOfMatches(in: newText, options: .reportProgress, range: NSRange(location: 0, length: (newText as NSString).length)) > 0
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

它同时使用逗号或点作为小数点分隔符。您还可以使用此模式限制小数位数:("^[0-9]*((\\.|,)[0-9]{0,2})?$"在本例中为 2)。


小智 6

对于Swift 2.3来防止用户在两个地方后输入十进制数 -

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    let decimalPlacesLimit = 2
    let rangeDot = txtPrice.text!.rangeOfString(".", options: .CaseInsensitiveSearch)

    if rangeDot?.count > 0
    {
        if (string == ".")
        {
            print("textField already contains a separator")
            return false
        }
        else {

            var explodedString = txtPrice.text!.componentsSeparatedByString(".")
            let decimalPart = explodedString[1]
            if decimalPart.characters.count >= decimalPlacesLimit && !(string == "")
            {
                print("textField already contains \(decimalPlacesLimit) decimal places")
                return false
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Viv*_*vek 6

斯威夫特 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
}
Run Code Online (Sandbox Code Playgroud)

目标-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;
}
Run Code Online (Sandbox Code Playgroud)


Kyl*_*egg 5

在接受的答案的基础上,以下方法验证了处理货币格式时有用的三种情况:

  1. 数量极大
  2. 小数点后超过2个字符
  3. 超过1小数点

确保正确设置了文本字段的委托,您的类符合UITextField协议,并添加以下委托方法.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
  // Check for deletion of the $ sign
  if (range.location == 0 && [textField.text hasPrefix:@"$"])
    return NO;

  NSString *updatedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
  NSArray *stringsArray = [updatedText componentsSeparatedByString:@"."];

  // Check for an absurdly large amount
  if (stringsArray.count > 0)
  {
    NSString *dollarAmount = stringsArray[0];
    if (dollarAmount.length > 6)
      return NO;
  }

  // Check for more than 2 chars after the decimal point
  if (stringsArray.count > 1)
  {
    NSString *centAmount = stringsArray[1];
    if (centAmount.length > 2)
      return NO;
  }

  // Check for a second decimal point
  if (stringsArray.count > 2)
    return NO;

  return YES;
}
Run Code Online (Sandbox Code Playgroud)