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

问题描述 投票:0回答:17

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

例如
2.5 好
2..5 不行

ios uitextfield decimal-point
17个回答
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;
}

这将创建一个由小数点分割的字符串数组,因此如果有一个以上的小数点,我们将在数组中至少有 3 个元素。


15
投票

这里是一个正则表达式的例子,例子限制只有一位小数和两位小数。你可以调整它以满足你的需要。

- (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;
}

9
投票

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
}

它使用逗号或点作为小数点分隔符。您还可以使用此模式限制小数位数:

"^[0-9]*((\\.|,)[0-9]{0,2})?$"
(在本例中为 2)。


8
投票

斯威夫特 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
}

目标-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;
}

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
            }
        }
    }
}

5
投票

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

  1. 数额极大
  2. 小数点后多于2个字符
  3. 小数点后一位以上

确保您的文本字段的委托设置正确,您的类符合

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;
}

2
投票
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    if(textField == min_textfield )
    {
        if([textField.text rangeOfString:@"."].location == NSNotFound)
        {
            if([string isEqualToString:@"."] )
            {
                flag_for_text = 1;
            }
            else 
            {
                textField.text = [NSMutableString stringWithFormat:@"%@",textField.text];
            }
        }
        else 
        {
            if([string isEqualToString:@"."])
            {
                return NO;
            }
            else 
            {
                textField.text = [NSMutableString stringWithFormat:@"%@",textField.text];
            }
        }
    }
}

2
投票

试试这个:-

public func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

    if(text == "," || text == "." ){
        let countdots = textView.text!.componentsSeparatedByString(".").count - 1

        if countdots > 0 && (text == "." || text == "," )
        {
            return false
        }
    }

    return true
}

1
投票

斯威夫特 3

无需创建数组和检查计数。这样限制用户只能放置 1 个小数点。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if (textField.text?.contains("."))! && string.contains(".")
    {
        return false
    }
    else
    {
        return true
    }
}

1
投票

斯威夫特 4

整数的最大数量为 4,即 9999,最大小数位数限制为 2。因此,最大数量可以为 9999.99

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


    // 100 is the tag value of our textfield
    /*or you may use "if textfield == myTextField{" if you have an IBOutlet to that textfield */
    if textField.tag == 100 {

        //max length limit of text is 8
        if textField.text!.count > 8 && string != "" {
            return false
        }

        let maxLength = 8
        let currentString: NSString = textField.text! as NSString 

// 使用以下代码如果您正在向该文本字段输入价格并希望在用户开始在该文本字段中输入时自动插入 $,或者您可以在开始处放置一些其他字符而不是 $。否则注释下面3行if条件代码

        if currentString.length == 0 {
            priceTextField.text = "$"
        }

//插入新输入字符后的新字符串

        let newString: NSString =
            currentString.replacingCharacters(in: range, with: string) as NSString


        if newString.length > maxLength{
            return false
        }

        if (textField.text!.range(of: ".") != nil) {
            let numStr = newString.components(separatedBy: ".")
            if numStr.count>1{
                let decStr = numStr[1]
                if decStr.length > 2{
                    return false
                }
            }
        }

        var priceStr: String = newString as String

        if (textField.text!.range(of: "$") != nil) {
            priceStr = priceStr.replacingOccurrences(of: "$", with: "")
        }

        let price: Double = Double(priceStr) ?? 0

        if price > 9999.99{
            return false
        }

        switch string {
        case "0","1","2","3","4","5","6","7","8","9":
            return true
        case ".":
            let array = Array(textField.text!)
            var decimalCount = 0
            for character in array {
                if character == "." {
                    decimalCount = decimalCount + 1
                }
            }

            if decimalCount == 1 {
                return false
            } else {
                return true
            }
        default:

            let array = Array(string)
            if array.count == 0 {
                return true
            }
            return false
        }
    }
    return true
}

1
投票

SWIFT 5

改进

信息:不允许:

  • 开头的分隔符
  • 零加上另一个数字,除非您在之后添加分隔符

1:将键盘类型设置为:Decimal Pad

2:复制过去

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    //!\ set the keyboard type to : Decimal Pad /!\\
    // CUSTOM SETUP
    let c = NSLocale.current.decimalSeparator ?? "."
    let limitBeforeSeparator = 2
    let limitAfterSeparator = 2
    // ---------
    
    
    var validatorUserInput:Bool = false
    
    let text = (textField.text ?? "") as NSString
    let newText = text.replacingCharacters(in: range, with: string)
    
    
    // Validator
    let pattern = "(?!0[0-9])\\d*(?!\\\(c))^[0-9]{0,\(limitBeforeSeparator)}((\\\(c))[0-9]{0,\(limitAfterSeparator)})?$"
    if let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) {
        validatorUserInput = regex.numberOfMatches(in: newText, options: .reportProgress, range: NSRange(location: 0, length: (newText as NSString).length)) > 0
    }
     
    
    if validatorUserInput {
        // setting data or something eles before the return
        if let char = string.cString(using: String.Encoding.utf8) {
            let isBackSpace = strcmp(char, "\\b")
            if (isBackSpace == -92 && textField.text?.count == 1) {
                print("Backspace was pressed")
                print(newText)
                // do something...
                
            } else {
                print("Number Added")
                print(newText)
                // do something...
                
            }
        }
        return validatorUserInput
    } else {
        return validatorUserInput
    }
}

3:在方法中设置,如果要分隔符前后最多x个位数

 let limitBeforeSeparator = 2 
 let limitAfterSeparator = 2

0
投票

在您将 UITextField 的委托设置为的任何对象中,添加一个方法来回答 "

[- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string]
".

然后您可以使用

NSNumberFormatter
对象,或者您可以强制检查已经存在的小数位标记(如果小数点已经存在则返回
NO
)。


0
投票

简写,数字格式如下

[NSString stringWithFormat:@"%9.5f", x];
其中5为“,”后的小数点。


0
投票

我做了一个解决方案,让你可以控制小数位数,所以用户可以只输入一个小数分隔符,你也可以控制小数位数。

只需正确设置decimalPlacesLimit值即可。

看方法:

- (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
投票

斯威夫特 4

在 UITextField 中避免多个小数点(. 或 ,)的有效且简单的方法:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if(string == "," || string == "." ){

        if ((textField.text?.contains(","))! || (textField.text?.contains("."))!){
            return false
        }
    }
    return true
}

0
投票
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if([string isEqualToString:@"."]) {
        BOOL containsDecimal = [textField.text containsString:@"."];
        return !containsDecimal;
    }
    return YES;
}

如果文本字段文本已经包含“.”然后返回 NO 否则返回 YES.


0
投票

谢谢大家,我需要限制点前后的数量。只有使用正则表达式,这对我来说才成为可能。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    if string == "," {
        textField.text = textField.text! + "."
        return false
    }
    
    
    guard let newTextField = textField.text else { return false }
    if !string.isEmpty {
        let text = newTextField as NSString
        let newText = text.replacingCharacters(in: range, with: string)
        if let regex = try? NSRegularExpression(pattern: "^[0-9]{0,4}$*((\\.|,)[0-9]{0,4})?$", options: .caseInsensitive) {
            return regex.numberOfMatches(in: newText, options: .reportProgress, range: NSRange(location: 0, length: (newText as NSString).length)) > 0
        }
        return false
    }
    return true
    
    //        @"^[0-9]{0,3}$*((\\.|,)[0-9]{0,2})?$"
    
}
© www.soinside.com 2019 - 2024. All rights reserved.