只允许UITextFieldinput的数字

iPad没有像iPhone / iPod那样的“Numpad”键盘。

我正在寻找如何限制用户的键盘只能接受0到9的值。

我会想象使用UITextField的“shouldChangeCharactersInRange”,但我不知道实现它的最好方法。

这是我如何处理SSNvalidation字段上的问题,如果需要,可以修改最大长度并删除if语句检查键盘types。

还有一种逻辑是在用户input时抑制最大长度警报,而不是粘贴数据。

在此代码的上下文中, BasicAlert()是一个#definemacros,它简单地显示了使用传递的标题和消息string的UIAlertViewUIAlertController

 // NOTE: This code assumes you have set the UITextField(s)'s delegate property to the object that will contain this code, because otherwise it would never be called. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // allow backspace if (!string.length) { return YES; } // Prevent invalid character input, if keyboard is numberpad if (textField.keyboardType == UIKeyboardTypeNumberPad) { if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound) { // BasicAlert(@"", @"This field accepts only numeric entries."); return NO; } } // verify max length has not been exceeded NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; if (proposedText.length > 4) // 4 was chosen for SSN verification { // suppress the max length message only when the user is typing // easy: pasted data has a length greater than 1; who copy/pastes one character? if (string.length > 1) { // BasicAlert(@"", @"This field accepts a maximum of 4 characters."); } return NO; } // only enable the OK/submit button if they have entered all numbers for the last four of their SSN (prevents early submissions/trips to authentication server) self.answerButton.enabled = (proposedText.length == 4); return YES; } 

您可以使用此代码只允许textField中的数字。

在那之前为textField设置委托

  textFieldName.delegate=self; 

要么

  [textFieldName setDelegate:self]; 

比使用这个代码只允许数字到文本字段

  - (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { //return yes or no after comparing the characters // allow backspace if (!string.length) { return YES; } ////for Decimal value start//////This code use use for allowing single decimal value // if ([theTextField.text rangeOfString:@"."].location == NSNotFound) // { // if ([string isEqualToString:@"."]) { // return YES; // } // } // else // { // if ([[theTextField.text substringFromIndex:[theTextField.text rangeOfString:@"."].location] length]>2) // this allow 2 digit after decimal // { // return NO; // } // } ////for Decimal value End//////This code use use for allowing single decimal value // allow digit 0 to 9 if ([string intValue]) { return YES; } return NO; } 

Swift代码的非常具体的步骤

您可以通过实现UITextFieldDelegate协议来提供限制func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool方法中的文本字段input的逻辑。

为了清楚起见,这些步骤假设您的故事板包含一个带有文本字段对象的视图控制器 ,该对象只能接受数字。

  1. 为扩展UIViewController的视图控制器创build一个自定义的类。 确保故事板中的场景通过在Xcode的Identity Inspector中设置自定义类的值来引用自定义类。

     import UIKit class YourCustomController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } } 
  2. 从您的场景的文本字段创build一个出口到您的自定义视图控制器。

     class YourCustomController: UIViewController { @IBOutlet weak var numberField: UITextField! ... } 
  3. 在自定义视图控制器中应用UITextFieldDelegate协议。

     class YourCustomController: UIViewController, UITextFieldDelegate { ... } 
  4. 在您的自定义视图控制器的viewDidLoad方法中,将您的文本字段的委托分配给您的自定义视图控制器类。

     override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self } 
  5. 添加UITextFieldDelegatefunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool方法。

    作为在上一步numberField自定义视图控制器设置为numberField的委托的结果,每次用户在文本字段中input字符时都会调用此方法。 如果你的方法返回true那么这个字符将保留在文本字段中。 如果你的方法返回false那么这个字符将不会保留在文本字段中。

    string参数是用户input的字符。 如果string字符可以转换为一个Int然后它是在0和9之间; 否则,它是一些非数字字符。

     class YourCustomController: UIViewController, UITextFieldDelegate { ... func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } } 

(请参阅下面的全视图控制器代码。)


示例视图控制器仅包含数字的文本字段

 import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } } 

带有十进制文本字段的示例视图控制器

如果你想支持一个十进制数然后利用NSNumberFormatter 。 查看代码评论的差异。

 import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! private var formatter: NSNumberFormatter! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self // Initialize the formatter; minimum value is set to zero; style is Decimal. formatter = NSNumberFormatter() formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle formatter.minimum = 0 } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // Combine the current text field value and the new string // character. If it conforms to the formatter's settings then // it is valid. If it doesn't then nil is returned and the // string character should not be allowed in the text field. return formatter.numberFromString("\(textField.text)\(string)") != nil } } 
 - (BOOL) textField: (UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { NSNumberFormatter * nf = [[NSNumberFormatter alloc] init]; [nf setNumberStyle:NSNumberFormatterNoStyle]; NSString * newString = [NSString stringWithFormat:@"%@%@",textField.text,string]; NSNumber * number = [nf numberFromString:newString]; if (number) return YES; else return NO; } 

我应用这个,它的工作原理!

 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9 } // Check for total length NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; } 
 NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; } 
 Works fine for me : - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound) && !(range.length==1 && string.length==0)) { return NO; } return YES; } 

试试这个以避免文本框清除问题

Swift 3.0

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { guard NSCharacterSet(charactersInString: "0123456789").isSupersetOfSet(NSCharacterSet(charactersInString: string)) else { return false } return true } 

Swift 4.0

  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else { return false } return true } 

保持内部表示不同的演示数据。 有一个更简单的方法。 让NSNumberFormatter做这个工作:

  NSNumberFormatter* ns = [[NSNumberFormatter alloc] init]; ns.numberStyle = NSNumberFormatterDecimalStyle; [ns setMaximumFractionDigits:2]; // This is your internal representation of the localized number double a = [[ns numberFromString:self.textIVA.text] doubleValue]]; [mylabel setText:[NSString stringWithFormat:@"€ %@", [NSNumberFormatter localizedStringFromNumber: [NSNumber numberWithDouble:a] numberStyle:NSNumberFormatterDecimalStyle]]]; 

如果你使用我的规范模式,那么代码看起来像这样

 textField.delegate = self lazy var specification: Specification = { return RegularExpressionSpecification(pattern: "^(|0|[1-9]\\d{0,6})$") }() func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let textFieldString: NSString = textField.text ?? "" let s = textFieldString.stringByReplacingCharactersInRange(range, withString:string) return specification.isSatisfiedBy(s) } func textFieldShouldReturn(textField: UITextField) -> Bool { let s = textField.text ?? "" let isTextValid = specification.isSatisfiedBy(s) if isTextValid { textField.resignFirstResponder() } return false } 

我已经修改@ iDev的答案为数字和“。”工作:

 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if ((character < 48) && (character != 46)) return NO; // 48 unichar for 0, and 46 unichar for point if (character > 57) return NO; // 57 unichar for 9 } // Check for total length NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; } 

使用此代码:

 NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; }