允许在iOS中的UITextField单个数字

我有一个Verification ViewController ,我通过短信得到4位validation码,我需要input这些代码login,我已经创build了这样的ViewController

正如你可以看到四个UITextField ,我需要只允许每个UITextField单个数字,

我试过:我试图使用shouldChangeCharactersInRange:method: ,但它没有被调用,我不知道什么是错的,我想因为UITextFieldUITableView所以它不工作。

您可以通过使用文本字段的委托function来更改文本字段。 最初,您需要设置每个文本字段的委托和标记。

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if ((textField.text.length >= 1) && (string.length > 0)) { NSInteger nextTag = textField.tag + 1; // Try to find next responder UIResponder* nextResponder = [textField.superview viewWithTag:nextTag]; if (! nextResponder) nextResponder = [textField.superview viewWithTag:1]; if (nextResponder) // Found next responder, so set it. [nextResponder becomeFirstResponder]; return NO; } return YES; } 

Swift 2

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // On inputing value to textfield if (textField.text?.characters.count < 1 && string.characters.count > 0){ let nextTag = textField.tag + 1; // get next responder var nextResponder = textField.superview?.viewWithTag(nextTag); if (nextResponder == nil){ nextResponder = textField.superview?.viewWithTag(1); } textField.text = string; nextResponder?.becomeFirstResponder(); return false; } else if (textField.text?.characters.count >= 1 && string.characters.count == 0){ // on deleting value from Textfield let previousTag = textField.tag - 1; // get next responder var previousResponder = textField.superview?.viewWithTag(previousTag); if (previousResponder == nil){ previousResponder = textField.superview?.viewWithTag(1); } textField.text = ""; previousResponder?.becomeFirstResponder(); return false; } return true; } 

斯威夫特4

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField.text!.count < 1 && string.count > 0{ let nextTag = textField.tag + 1 // get next responder var nextResponder = textField.superview?.viewWithTag(nextTag) if (nextResponder == nil){ nextResponder = textField.superview?.viewWithTag(1) } textField.text = string nextResponder?.becomeFirstResponder() return false } else if textField.text!.count >= 1 && string.count == 0{ // on deleting value from Textfield let previousTag = textField.tag - 1 // get next responder var previousResponder = textField.superview?.viewWithTag(previousTag) if (previousResponder == nil){ previousResponder = textField.superview?.viewWithTag(1) } textField.text = "" previousResponder?.becomeFirstResponder() return false } return true } 

如果你不想使用标签,那么使用这个代码,它会比上面更好

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // On inputing value to textfield if ((textField.text?.characters.count)! < 1 && string.characters.count > 0){ if(textField == txtOne){ txtTwo.becomeFirstResponder() } if(textField == txtTwo){ txtThree.becomeFirstResponder() } if(textField == txtThree){ txtFour.becomeFirstResponder() } textField.text = string return false }else if ((textField.text?.characters.count)! >= 1 && string.characters.count == 0){ // on deleting value from Textfield if(textField == txtTwo){ txtOne.becomeFirstResponder() } if(textField == txtThree){ txtTwo.becomeFirstResponder() } if(textField == txtFour) { txtThree.becomeFirstResponder() } textField.text = "" return false }else if ((textField.text?.characters.count)! >= 1 ){ textField.text = string return false } return true } 

它可以实现使用UITextField委托和通过设置标签为每个文本字段按升序(比如1 – 4),下面是委托处理程序来解决问题。

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // On inputing value to textfield if (textField.text?.characters.count < 1 && string.characters.count > 0){ let nextTag = textField.tag + 1; // get next responder var nextResponder = textField.superview?.viewWithTag(nextTag); if (nextResponder == nil){ nextResponder = textField.superview?.viewWithTag(1); } textField.text = string; nextResponder?.becomeFirstResponder(); return false; } else if (textField.text?.characters.count >= 1 && string.characters.count == 0){ // on deleteing value from Textfield let previousTag = textField.tag - 1; // get next responder var previousResponder = textField.superview?.viewWithTag(previousTag); if (previousResponder == nil){ previousResponder = textField.superview?.viewWithTag(1); } textField.text = ""; previousResponder?.becomeFirstResponder(); return false; } return true; } 

我带了一个隐藏的文本字段和四个imageViews与两个图像。 一个为空白和其他Bullet相同的iOS默认。

还为四个图像设置标签。

在加载设置引脚代码焦点

 - (void)startPinCode { txtPinCodeLockDigits.text = @""; for (int i = 1; i <= 4; i++) { UIImageView *img = (UIImageView *)[self.view viewWithTag:i]; [img setImage:[UIImage imageNamed:@"Img_BG_PinCode.png"]]; } [txtPinCodeLockDigits becomeFirstResponder]; } 

然后根据用户input更改imageview的图像,只允许四个字符

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string]; textField.text = result; for (int i = 1; i <= 4; i++) { UIImageView *img = (UIImageView *)[self.view viewWithTag:i]; if (i <= [result length]) [img setImage:[UIImage imageNamed:@"Img_BG_PinCode_Filled.png"]]; else [img setImage:[UIImage imageNamed:@"Img_BG_PinCode.png"]]; } NSLog(@"Result :: %@", result); if ([result length] == 4) { [self performSelector:@selector(keyGenerationForApplication:) withObject:result afterDelay:0.2]; } return NO; } 

四个字符调用生成的PIN码function后,将其存储在与iOS默认PIN设置相同的用户默认值中

 - (void)keyGenerationForApplication:(NSString *)pinCode { int appCode = [pinCode intValue]; [DefaultsValues setIntegerValueToUserDefaults:appCode ForKey:PIN_LOCK_PATTERN]; } 

在这里,您可以再次调用StartPinCode方法来重新确认代码。

希望它能帮助你。
谢谢

迅速2.3

  class BankDepositsWithOTPVC: UIViewController { let limitLength = 1 override func viewDidLoad() { super.viewDidLoad() } } // MARK: Textfield Validator extension BankDepositsWithOTPVC : UITextFieldDelegate { func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // On inputing value to textfield if (textField.text?.characters.count < 1 && string.characters.count > 0){ let nextTag = textField.tag + 1; // get next responder let nextResponder = textField.superview?.viewWithTag(nextTag); if (nextResponder == nil){ textField.resignFirstResponder() // nextResponder = textField.superview?.viewWithTag(1); } textField.text = string; nextResponder?.becomeFirstResponder(); return false; }else if (textField.text?.characters.count >= 1 && string.characters.count > 0){ // maximum 1 digit textField.text = ""; let nextTag = textField.tag + 1; // get next responder let nextResponder = textField.superview?.viewWithTag(nextTag); if (nextResponder == nil){ textField.resignFirstResponder() // nextResponder = textField.superview?.viewWithTag(1); } textField.text = string; nextResponder?.becomeFirstResponder(); return false; } else if (textField.text?.characters.count >= 1 && string.characters.count == 0){ // on deleteing value from Textfield let previousTag = textField.tag - 1; // get next responder var previousResponder = textField.superview?.viewWithTag(previousTag); if (previousResponder == nil){ previousResponder = textField.superview?.viewWithTag(1); } textField.text = ""; previousResponder?.becomeFirstResponder(); return false; } //return true; guard let text = textField.text else { return true } let newLength = text.characters.count + string.characters.count - range.length return newLength <= limitLength } } 

Objective-C的

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ if ((textField.text.length < 1) && (string.length > 0)) { NSInteger nextTag = textField.tag + 1; UIResponder* nextResponder = [textField.superview viewWithTag:nextTag]; if (! nextResponder){ [textField resignFirstResponder]; } textField.text = string; if (nextResponder) [nextResponder becomeFirstResponder]; return NO; }else if ((textField.text.length >= 1) && (string.length > 0)){ //FOR MAXIMUM 1 TEXT NSInteger nextTag = textField.tag + 1; UIResponder* nextResponder = [textField.superview viewWithTag:nextTag]; if (! nextResponder){ [textField resignFirstResponder]; } textField.text = string; if (nextResponder) [nextResponder becomeFirstResponder]; return NO; } else if ((textField.text.length >= 1) && (string.length == 0)){ // on deleteing value from Textfield NSInteger prevTag = textField.tag - 1; // Try to find prev responder UIResponder* prevResponder = [textField.superview viewWithTag:prevTag]; if (! prevResponder){ [textField resignFirstResponder]; } textField.text = string; if (prevResponder) // Found next responder, so set it. [prevResponder becomeFirstResponder]; return NO; } return YES; } 

试试这个示例教程密码锁

ViewController.h

 #import <UIKit/UIKit.h> @interface ViewController : UIViewController<UITextFieldDelegate> { IBOutlet UITextField *txtPassword; } @end 

ViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; txtPassword.delegate=self; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSUInteger newLength = [textField.text length] + [string length] - range.length; return (newLength > 1) ? NO : YES; } 

只需使用TextFieldDelegate方法,并在每次更改后检查TextFieldDelegate的长度

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string) if newString.characters.count == 1 { nextTextField.becomeFirstResponder() return true } else { return false } } 

像1,2,3,4一样提供标签到文本框,并直接使用它

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool let next:NSInteger if string == "" { next = textField.tag - 1; } else{ next = textField.tag + 1; } if (textField.text?.characters.count)! >= 1 { if textField.tag == 4 { if string == "" { textField.text = "" let temptf = self.view.viewWithTag(next) as! UITextField temptf.becomeFirstResponder() return false } else{ if (textField.text?.characters.count)! > 1 { let stringg = textField.text! textField.text = stringg.replacingOccurrences(of: stringg, with: string) } return false } } else{ if string == "" { textField.text = "" if next != 0 { let temptf = self.view.viewWithTag(next) as! UITextField temptf.becomeFirstResponder() } return false } else{ if (textField.text?.characters.count)! > 1 { let stringg = textField.text! textField.text = stringg.replacingOccurrences(of: stringg, with: string) } let temptf = self.view.viewWithTag(next) as! UITextField temptf.becomeFirstResponder() } } } return true } 

Swift 3中修改了Anurag Soni的答案。

  • 它假定您有名为textFields出口集合,并且文本字段已设置了有序标签
  • 它增加了文本字段中已经有一些数字,并且当用户input新的东西 – 数字被replace时的情况
  • input仅限于数字
  • 它防止粘贴多个数字

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // Restrict to only digits let aSet = NSCharacterSet(charactersIn:"0123456789").inverted let compSepByCharInSet = string.components(separatedBy: aSet) let numberFiltered = compSepByCharInSet.joined(separator: "") if string != numberFiltered { return false } // Get the unwrapped text guard let text = textField.text else { return false } if (text.characters.count < 1 && string.characters.count == 1) { // New value to empty text field textField.text = string // Next responder if let someTextField = (textFields.filter { $0.tag == textField.tag + 1 }).first { someTextField.becomeFirstResponder() } else { view.endEditing(true) } return false } else if (text.characters.count >= 1 && string.characters.count == 0){ // On deleting value from Textfield textField.text = "" // Previous responder if let someTextField = (textFields.filter { $0.tag == textField.tag - 1 }).first { someTextField.becomeFirstResponder() } else { view.endEditing(true) } return false } else if string.characters.count == 1 { // There's already some digit in text field // Replace it with new one textField.text = string // Next responder if let someTextField = (textFields.filter { $0.tag == textField.tag + 1 }).first { someTextField.becomeFirstResponder() } else { view.endEditing(true) } } return false } 

试试这个: – 对于swift 3.0

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // On inputing value to textfield if ((textField.text?.characters.count)! < 1 && string.characters.count > 0){ let nextTag = textField.tag + 1; // get next responder let nextResponder = textField.superview?.viewWithTag(nextTag); textField.text = string; if (nextResponder == nil){ textField.resignFirstResponder() } nextResponder?.becomeFirstResponder(); return false; } else if ((textField.text?.characters.count)! >= 1 && string.characters.count == 0){ // on deleting value from Textfield let previousTag = textField.tag - 1; // get next responder var previousResponder = textField.superview?.viewWithTag(previousTag); if (previousResponder == nil){ previousResponder = textField.superview?.viewWithTag(1); } textField.text = ""; previousResponder?.becomeFirstResponder(); return false; } return true; } 

转换Anurag Soni答案在3.0

你只需要实现这个方法。