【问题标题】:UITextField accepting only one decimal point with max 3 digits before decimal point & max 2 digits after decimal pointUITextField 只接受一个小数点,小数点前最多 3 位,小数点后最多 2 位
【发布时间】:2019-03-24 19:27:16
【问题描述】:

我想限制UITextField 只接受一位小数。

小数点前最多允许 3 位数字,小数点后最多允许 2 位数字。

请注意,最小位数可以是 1,不能先输入小数。

我怎样才能实现它?

【问题讨论】:

  • 为您的文本字段指定一个委托,并使用shouldChangeCharactersInRange:textFieldShouldEndEditing: 评估内容,具体取决于您希望如何处理错误输入。

标签: ios uitextfield uitextfielddelegate


【解决方案1】:

您可以将以下代码用于相同的场景。

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
NSString *expression = @"^([0-9]*)(\\.([0-9]+)?)?$";

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger noOfMatches = [regex numberOfMatchesInString:newStr options:0 range:NSMakeRange(0,[newStr length])];

    if (noOfMatches==0)
    {
        return NO;
    }

NSUInteger newLength = [textField.text length] + [string length] - range.length;
    if(range.length + range.location > textField.text.length)
    {
        return NO;
    }
    if ([newStr containsString:@"."])
    {
        return newLength <= 6;
    }
    return newLength <= 3;

    //  return YES;
}

. 被视为一个字符。所以总共是6个字符。您可以调整条件中的值。

【讨论】:

    【解决方案2】:

    这是您可以使用 Swift正则表达式 实现它的方法:

    1. 设置文本字段的委托。这可以在代码或 IB 中完成。

    2. 要验证用户输入的文本,您可以将类似于以下内容的代码添加到您的委托中:

      // Number of digits that are allowed before decimal point
      let kMaximumIntegerDigits = 3
      // Number of digits that are allowed after decimal point
      let kMaximumFractionDigits = 2
      
      func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
      
      // The replacement string is empty when the user have removed some characters.
      if string.isEmpty == true { return true }
      
      // Get the current string the text field holds.
      let currentText = textField.text ?? ""
      
      // Check the limits.
      if (string.characters.count + currentText.characters.count) > 6 { return false }
      
      // Get the string we are expecting to obtain after the replacement.
      var resultingText = currentText
      resultingText.insertContentsOf(string.characters, at: currentText.startIndex.advancedBy(range.location))
      
      // Check the final string with the help of the regular expression.
      let regex = "^(?:(?:[0-9]{1,\(kMaximumIntegerDigits)}[.][0-9]{0,\(kMaximumFractionDigits)})|(?:[0-9]){1,\(kMaximumIntegerDigits)})$"
      let regexRange = resultingText.rangeOfString(regex, options: .RegularExpressionSearch)
      if regexRange == nil { return false }
      
      return true
      
      }
      
    3. 最后,您应该在用户尝试结束编辑会话时验证结果文本。你可以这样做:

      func textFieldShouldEndEditing(textField: UITextField) -> Bool {
       // Get the current input string.
       guard let currentText = textField.text else { return false }
      
       // Create the regular expression for the final check.
       let regex = "^(?:(?:[0-9]{1,\(kMaximumIntegerDigits)}[.][0-9]{1,\(kMaximumFractionDigits)})|(?:[0-9]){1,\(kMaximumIntegerDigits)})$"
       let regexRange = currentText.rangeOfString(regex, options: .RegularExpressionSearch)
       if regexRange == nil { 
       // Show an alert to the user with the message that explains what the input is expected...
       return false 
       }
      
       // Make additional clean-up and finalize the editing session.
       return true
      }
      

    【讨论】:

      【解决方案3】:

      非常感谢大家的帮助。通过参考我在答案下方框定的那些答案。

      编辑

      虽然文本字段具有例如462. & 用户将退格结果触摸到 462,理想情况下应该导致 46

          - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
          {
              NSString *strTextField = [textField.text stringByReplacingCharactersInRange:range withString:string];
          // restrict textfield from entering ./0 at first place
          if (strTextField.length > 0) {
              NSString *theCharacterAtIndex0 = [NSString stringWithFormat:@"%c", [strTextField characterAtIndex:0]];
              if ([theCharacterAtIndex0 isEqualToString:@"."] || [theCharacterAtIndex0 isEqualToString:@"0"]) {
                  return NO;
              }
          }
          //    NSLog(@"%@ , %@", textField.text, strTextField);
      
          // automatically add decimal point after 3 digits entered
          if (![textField.text containsString:@"."]) {
              if (strTextField.length == MAX_LENGTH_BeforeDecimal && ![strTextField containsString:@"."]) {
                  strTextField = [strTextField stringByAppendingString:@"."];
                  textField.text = strTextField;
                  return NO;
              }
          }
      
          // when decimal is deleted
          if ([textField.text containsString:@"."]) {
              if (![strTextField containsString:@"."]) {
                  int indeOfdecimal = (int)[textField.text rangeOfString:@"."].location;
                  NSString *strBeforeDecimal = [textField.text substringToIndex:indeOfdecimal];
                  textField.text = strBeforeDecimal;
              }
          }
      
          NSArray *separator = [strTextField componentsSeparatedByString:@"."];
          // to restrict textfield to single decimal
          if([separator count] > 2 ) {
              return NO;
          }
          if([separator count] >= 2) {
              // restrict the max digits before & after decimal points
              NSString *sepStr0 = [NSString stringWithFormat:@"%@",[separator objectAtIndex:0]];
              NSString *sepStr1 = [NSString stringWithFormat:@"%@",[separator objectAtIndex:1]];
              if ([sepStr0 length] > 3) {
                  return NO;
              }
              if ([sepStr1 length] > 2) {
                  return NO;
              }
          }
          return YES;
      }
      

      【讨论】:

        【解决方案4】:

        使用这个正则表达式代码:

        - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
           // Only allow one decimal point and 2 digits after it
           NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
           NSString *expression = @"^[0-9]{0,3}$*((\\.|,)[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;
           return YES;
         }
        

        这里使用的正则表达式是 "^[0-9]{0,3}$*((\.|,)[0-9]{0,2强>})?$"。

        这里的数字 3(第一个粗体)表示小数点前的字符,数字 2(第二个粗体)表示小数点后的字符。

        您可以使用此正则表达式并根据您的要求创建规则。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-23
          • 2015-08-20
          相关资源
          最近更新 更多