Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何限制UITextField中的小数点数量?_Ios_Uitextfield_Decimal Point - Fatal编程技术网

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

Ios 如何限制UITextField中的小数点数量?,ios,uitextfield,decimal-point,Ios,Uitextfield,Decimal Point,我有一个UITextField,当单击它时,会显示一个左下角有小数点的数字键盘。我试图限制该字段,以便用户只能放置1个小数点 e、 g. 2.5正常 2..5不正常在将UITextField的委托设置为的任何对象中,添加一个响应的方法 然后,您可以使用NSNumberFormatter对象,也可以强制检查已存在的小数点标记(如果已存在小数点标记,则返回NO)实现shouldChangeCharactersRange方法,如下所示: // Only allow one decimal point

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

e、 g.
2.5正常

2..5不正常

在将UITextField的委托设置为的任何对象中,添加一个响应的方法


然后,您可以使用
NSNumberFormatter
对象,也可以强制检查已存在的小数点标记(如果已存在小数点标记,则返回
NO

实现shouldChangeCharactersRange方法,如下所示:

// 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个元素。

简而言之,数字格式如下
[NSString stringWithFormat:@“%9.5f”,x]其中5是“,”之后的小数点

这里是一个正则表达式示例,该示例仅限于一个小数点和两个小数点。你可以调整它以满足你的需要

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

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

  • 极大量
  • 小数点后超过2个字符
  • 超过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;
    }
    

    我提出了一个解决方案,它可以控制小数点计数,所以用户只能键入一个小数点分隔符,还可以控制小数点计数

    只需正确设置小数点值即可

    参见方法:

    - (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;
    }
    
    试试这个:-

    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
    }
    

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

    Swift 3

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

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if (textField.text?.contains("."))! && string.contains(".")
        {
            return false
        }
        else
        {
            return true
        }
    }
    
    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]*((\\.\124;,)[0-9]{0,2})?$”
    (在本例中为2)。

    Swift 4

    在UITextField中避免多个小数点(.or,)的高效简便方法:

        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
    }
    
    斯威夫特4
    func textField(textField:UITextField,shouldChangeCharacters范围:NSRange,replacementString:string)->Bool{
    //允许删除字符(退格)
    如果字符串==“”{
    返回真值
    }
    //块多点
    if(textField.text?.contains(“.”)!&&string==”{
    返回错误
    }
    //请勾选这里的小数位
    如果(textField.text?.contains(“.”){
    设limitDecimalPlace=2
    设decimalPlace=textField.text?.components(以“.”分隔)。最后
    如果(小数点?.count)!
    目标-C
    //在.h文件或.m文件中创建此变量
    浮点数;
    //在viewDidLoad方法中赋值
    numberOfDecimal=2;
    #pragma标记-TextFieldDelegate
    -(BOOL)textField:(UITextField*)textField应更改字符范围:(NSRange)范围替换字符串:(NSString*)字符串{
    //允许删除字符(退格)
    if([string IsequalString:@”“){
    返回true;
    }
    //块多点
    if([textField.text containssString:@.”)和&[string IsequalString:@.”){
    返回false;
    }
    //请勾选这里的小数位
    if([textField.text包含字符串:@”。)){
    NSString*strDecimalPlace=[[textField.text componentsSeparatedByString:@.'']lastObject];
    if(strDecimalPlace.length<\u numberOfDecimal){
    返回true;
    }
    否则{
    返回false;
    }
    }
    返回true;
    }
    
    Swift 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
    }
    
    如果文本字段文本已包含“.”,则返回否,否则返回是。

    SWIFT 5 改进

    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
        }
    }
    
    信息:不允许:

    • 开头的分隔符
    • 零加上开始处的另一个数字,除非在后面添加分隔符
    1:将键盘类型设置为:十进制键盘

    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
    

    您可以使用NSRegularExpression来确定新闻字符串是否包含多个十进制数,而不是使用componentsSeparatedByString。真!有很多方法可以做到这一点。我通常使用它是因为我经常想对整数和小数部分做一些不同的事情。使用正则表达式可以更好地控制textfield接受的字符以及它们将采用的格式。@nizx对于这种特定情况,我认为这并不重要,尽管您的示例较长且“看起来”对于新用户来说更复杂。对于更复杂的示例,您很可能是对的,或者如果它们是数字,那么使用NSNumberFormatter也可能是合适的。对于十进制分隔符,您也可以从[[NSLocale currentLocale]objectForKey:NSLocaleEdecimalSeparator]]获得它,而不是@“.”。这样,代码也可以正确地用于usi区域
    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
        }
    }
    
     let limitBeforeSeparator = 2 
     let limitAfterSeparator = 2