【问题标题】:UITextField Should accept number only valuesUITextField 应该只接受数字值
【发布时间】:2012-05-30 21:18:19
【问题描述】:

我有 UITexfields,我希望它只接受输入数值的其他数字显示警报。 我希望motionSicknessTextFiled 应该只接受数字

NSString*dogswithMotionSickness=motionSicknessTextField.text;
NSString*valueOne=cereniaTextField.text;
NSString*valueTwo=prescriptionTextField.text;
NSString*valueThree=otherMeansTextField.text;
NSString*valueFour=overtheCounterTextField.text;

【问题讨论】:

标签: ios objective-c iphone xcode uitextfield


【解决方案1】:

在您从中获取这些值的任何 UITextField 中,您都可以指定当有人在文本字段内触摸时想要显示的键盘类型。

例如纯数字键盘。

喜欢这个截图:

在使用 Xcode 内置的 XIB 和 Interface Builder 时,这很容易设置,但如果您想以编程方式理解这一点,请查看 Apple 的 UITextInputTraits protocol reference page, specifically the keyboardType property 信息。

要过滤掉标点符号,请设置文本字段的委托并设置 shouldChangeCharactersInRange 方法:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:textField.text];

    BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
    return stringIsValid;
}

【讨论】:

  • 另外,使用 DecimalPad 获取十进制输入(浮点数)。
  • 在创建characterSetFromTextField 时应使用[textField.text stringByReplacingCharactersInRange:range withString:string] 而不是textField.text,因为text 属性尚未更新。
  • 在 xcode 7 中,您可以在属性检查器选项卡中找到此选项。有一个称为键盘类型的选项。
  • 此代码允许第一个字符为字母。如何解决?
  • @R.Mohan 您是否将键盘类型设置为数字?确保从该方法中为任何字母字符返回“false”。
【解决方案2】:

目标 C

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (!string.length) 
        return YES;

    if (textField == self.tmpTextField)
    {
        NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
        NSString *expression = @"^([0-9]+)?(\\.([0-9]{1,2})?)?$";
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression 
                                                                               options:NSRegularExpressionCaseInsensitive 
                                                                                 error:nil];
        NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString
                                                            options:0
                                                              range:NSMakeRange(0, [newString length])];        
        if (numberOfMatches == 0)
            return NO;        
    }
    return YES;
}

Swift 3.0

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if !string.characters.count {
        return true
    }
    do {
        if textField == self.tmpTextField {
            var newString = textField.text.replacingCharacters(inRange: range, with: string)
            var expression = "^([0-9]+)?(\\.([0-9]{1,2})?)?$"
            var regex = try NSRegularExpression(pattern: expression, options: NSRegularExpressionCaseInsensitive)
            var numberOfMatches = regex.numberOfMatches(inString: newString, options: [], range: NSRange(location: 0, length: newString.characters.count))
            if numberOfMatches == 0 {
                return false
            }
        }
    }
    catch let error {
    }
    return true
}

【讨论】:

  • 这不允许您在完成编辑后删除字符。
  • @RahulSharma 在此示例中,您可以通过检查string 参数的长度并在字符串为空时返回YES 来允许删除字符。类似if (!string.length) return YES;
【解决方案3】:
[textField setKeyboardType:UIKeyboardTypeNumberPad];

【讨论】:

  • 并且不会停止复制意大利面或硬件键盘
【解决方案4】:

我已经实现了具有 textField 功能的 sn-p:

  1. 检查允许的最大字符数
  2. 检查有效的小数数字。
  3. 只检查数字数字。

代码是UITextField 委托方法。在使用此 sn-p 之前,您必须具备以下属性:

  1. self.maxCharacters
  2. self.numeric // 只有 int 个字符。
  3. self.decimalNumeric // 只有数字和“.”、“”(针对特定语言环境,如俄语)。

代码:

- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if(self.numeric || self.decimalNumeric)
    {
        NSString *fulltext = [textField.text stringByAppendingString:string];
        NSString *charactersSetString = @"0123456789";

        // For decimal keyboard, allow "dot" and "comma" characters.
        if(self.decimalNumeric) {
            charactersSetString = [charactersSetString stringByAppendingString:@".,"];
        }

        NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:charactersSetString];
        NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:fulltext];

        // If typed character is out of Set, ignore it.
        BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
        if(!stringIsValid) {
            return NO;
        }

        if(self.decimalNumeric)
        {
            NSString *currentText = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

            // Change the "," (appears in other locale keyboards, such as russian) key ot "."
            currentText = [currentText stringByReplacingOccurrencesOfString:@"," withString:@"."];

            // Check the statements of decimal value.
            if([fulltext isEqualToString:@"."]) {
                textField.text = @"0.";
                return NO;
            }

            if([fulltext rangeOfString:@".."].location != NSNotFound) {
                textField.text = [fulltext stringByReplacingOccurrencesOfString:@".." withString:@"."];
                return NO;
            }

            // If second dot is typed, ignore it.
            NSArray *dots = [fulltext componentsSeparatedByString:@"."];
            if(dots.count > 2) {
                textField.text = currentText;
                return NO;
            }

            // If first character is zero and second character is > 0, replace first with second. 05 => 5;
            if(fulltext.length == 2) {
                if([[fulltext substringToIndex:1] isEqualToString:@"0"] && ![fulltext isEqualToString:@"0."]) {
                    textField.text = [fulltext substringWithRange:NSMakeRange(1, 1)];
                    return NO;
                }
            }
        }
    }

    // Check the max characters typed.
    NSUInteger oldLength = [textField.text length];
    NSUInteger replacementLength = [string length];
    NSUInteger rangeLength = range.length;

    NSUInteger newLength = oldLength - rangeLength + replacementLength;
    BOOL returnKey = [string rangeOfString: @"\n"].location != NSNotFound;

    return newLength <= _maxCharacters || returnKey;
}

演示:

【讨论】:

  • 你有这个的 Swift 3 版本吗?
【解决方案5】:

修改了 Michael Dautermann 的回答:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if(string.length > 0)
    {
        NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
        NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:string];

        BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
        return stringIsValid;
    }
    return YES;
}

【讨论】:

    【解决方案6】:

    斯威夫特 4

    这里只允许输入数字,也可以设置字符限制

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
      let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
      let compSepByCharInSet = string.components(separatedBy: aSet)
      let numberFiltered = compSepByCharInSet.joined(separator: "")
    
      if string == numberFiltered {
        let currentText = textField.text ?? ""
        guard let stringRange = Range(range, in: currentText) else { return false }
        let updatedText = currentText.replacingCharacters(in: stringRange, with: string)
        return updatedText.count <= 10
      } else {
        return false
      }
    }
    

    【讨论】:

      【解决方案7】:

      这里是 Swift 解决方案:

      在 viewDidLoad 中设置委托:

      _yourTextField.delegate = self
      
      let _acceptableCharacters = "0123456789."
      
      func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
      
          if (string.characters.count == 0) {
              return true
          }
      
          if (textField == self._yourTextField) {
              let cs = NSCharacterSet(charactersInString: self._acceptableCharacters)
              let filtered = string.componentsSeparatedByCharactersInSet(cs).filter {  !$0.isEmpty }
              let str = filtered.joinWithSeparator("")
      
              return (string != str)
          }
      
          return true
      }
      

      【讨论】:

      • 如何限制 UITextfield 只接收数字并限制 6 到 8 之间的数字数量?
      【解决方案8】:

      这是检查字符串是否仅包含数字值的函数

      +(BOOL) checkforNumeric:(NSString*) str
      {
          NSString *strMatchstring=@"\\b([0-9%_.+\\-]+)\\b"; 
          NSPredicate *textpredicate=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", strMatchstring];
      
          if(![textpredicate evaluateWithObject:str])
          {
              //////NSLog(@"Invalid email address found");
              UIAlertView *objAlert = [[UIAlertView alloc] initWithTitle:APP_NAME message:@"please enter valid text." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Close",nil];
              [objAlert show];
              [objAlert release];
              return FALSE;
          }
          return TRUE;
      }
      

      在提交按钮上检查它。

      【讨论】:

        【解决方案9】:

        This answer 在 Swift 3 中抛出了一些错误,这是有效的答案:

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            if string.characters.count == 0 {
                return true
            }
            do {
                if textField == self.numberTextField {
        
                    let nString = textField.text as NSString?
                    let newString = nString?.replacingCharacters(in: range, with: string)
                    let expression = "^([0-9]+)?(\\.([0-9]{1,2})?)?$"
                    let regex = try NSRegularExpression(pattern: expression, options: .caseInsensitive)
                    let numberOfMatches = regex.numberOfMatches(in: newString! as String, options: [], range: NSRange(location: 0, length: (newString?.characters.count)!))
        
                    if numberOfMatches == 0 {
                        return false
                    }
                }
            }
            catch let error {
            }
            return true
        }
        

        【讨论】:

          【解决方案10】:

          我刚刚修改了 Michael 的答案,让它更容易实现。只需确保您的 UITextfield 的代表设置为自身即可。

          yourTxtField.delegate = self;
          

          此外,将此代码复制并粘贴到您的主文件中。

          - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  {
          
              if (textField == yourTxtField) {
                  NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
                  NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:string];
          
                  BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
                      return stringIsValid;
                  }else {
                      return YES;
                  }
              }
          

          如果你想允许空格键的使用,只需在CharactersInString末尾的空格处放一个空格,就像这样:

          @"0123456789" -> @"0123456789 "
          

          另外:

          如果您想限制字符串的长度,只需将 if 函数替换为以下内容:

          if (textField == yourTxtField) {
                  NSUInteger newLength = [textField.text length] + [string length] - range.length;
                  NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"1234567890"] invertedSet];
                  NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
                  return (([string isEqualToString:filtered])&&(newLength <= 10));
          
              }
          

          在我的例子中,末尾的“10”代表字符的限制。

          干杯! :)

          【讨论】:

            【解决方案11】:

            @almas-adlibek 提供的最佳答案的 Swift 4.2 端口

            一堆配置变量:

            private let kMaxTextLength = 8
            private let kZeroDotted = "0."
            private let kZero = "0"
            private let kDoubleDot = ".."
            private let kDot = "."
            private let kPeriod = ","
            

            现在 Swift 4 转换了部分代码。

             func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            
                guard let oldText = textField.text, let swiftRange = Range(range, in: oldText) else {
                    return true
                }
            
                let newText = oldText.replacingCharacters(in: swiftRange, with: string)
            
                var currentText =  textField.text?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
            
                // Change the "," (appears in other locale keyboards, such as russian) key ot "."
                currentText = currentText?.replacingOccurrences(of: kPeriod, with: kDot)
            
                // Check the statements of decimal value.
                if (newText == kDot) {
                    textField.text = kZeroDotted;
                    return false
                }
            
                if (newText.range(of: kDoubleDot) != nil) {
                    textField.text = newText.replacingOccurrences(of: kDoubleDot, with: kDot);
                    return false
                }
            
                // If second dot is typed, ignore it.
                let dots = newText.components(separatedBy: kDot)
                if(dots.count > 2) {
                    textField.text = currentText;
                    return false
                }
            
                // If first character is zero and second character is > 0, replace first with second. 05 => 5;
                if(newText.count == 2) {
                    if(newText[0...0] == kZero && newText != kZeroDotted) {
                        textField.text = newText[1...1]
                        return false
                    }
                }
            
                // Check the max characters typed.
                let oldLength = textField.text?.count ?? 0
                let replacementLength = string.count
                let rangeLength = range.length
            
                let newLength = oldLength - rangeLength + replacementLength;
                let returnKey = string.rangeOfCharacter(from: CharacterSet.newlines) != nil
            
                return newLength <= kMaxTextLength || returnKey;
            }
            

            【讨论】:

              【解决方案12】:

              斯威夫特

              class ExampleVC: UIViewController {
              
                  let numbers = "0123456789";
              
                  override func viewDidLoad() {
                      super.viewDidLoad()
              
                      let textfield = UITextField(frame: CGRectMake(20, 100, 300, 44))
                      //make some customization, if you want
                      self.view.addSubview(textfield)
              
                      textfield.delegate = self;
                  }
              }
              
              extension ExampleVC: UITextFieldDelegate {
              
                  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                      return string.characters.count > 0 ? numbers.contains(string) : true
                  }
              }
              

              【讨论】:

                【解决方案13】:

                在文本字段中仅输入数值的另一种选择是选择相应文本字段的键盘类型属性。附上截图供参考。

                【讨论】:

                • 你能用你正在使用的图标分享文本字段的代码吗?
                • 在 iPad 上,数字键盘默认为普通键盘并选择了 shift。用户仍然可以切换回字母。此外,用户可以在任何设备上复制和粘贴任何文本。
                【解决方案14】:

                这是 swift 4

                的工作示例
                public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
                {
                    // Allow Backspace
                    if string.count == 0 {
                        return true
                    }
                
                    // Allow Only Valid Decimal Numbers
                    if let textFieldText = textField.text   {
                
                        let finalText = (textFieldText as NSString).replacingCharacters(in: range, with: string)
                        if Double(finalText) != nil {
                            return true
                        }
                    }
                    return false
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-10-16
                  相关资源
                  最近更新 更多