允许在iOS的UITextField中使用单个数字

时间:2021-01-01 22:09:32

I have a Verification ViewController, I get 4 digit verification code by SMS and I need to enter those code to login, I have created the ViewController like this

我有一个验证视图控制器,我通过SMS得到4位验证码我需要输入这些代码来登录,我创建了这样的视图控制器

允许在iOS的UITextField中使用单个数字

As you can see four UITextFields, I need to allow only single digit for each UITextField,

正如您看到的四个UITextField,我需要为每个UITextField只允许一个数字,

What I tried: I was trying to use shouldChangeCharactersInRange:method: , but its not getting called, I don't know what's wrong, I think because UITextFields are in UITableView so it is not working.

我的尝试:我试图使用shouldChangeCharactersInRange:method:,但是它没有被调用,我不知道哪里出错了,我认为因为UITextFields在UITableView中,所以它不工作。

10 个解决方案

#1


17  

You can change the text field like this by using the delegate function of the text field. Initially, you need to set the delegate and the tag of each text field.

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

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

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

Swift 4

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

}

#2


7  

use this code if you don't want work with tag and it works better then above

如果您不想使用标记,请使用此代码,并且它比上面更好地工作

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
    }

#3


3  

It can be achieve using UITextField delegate & by setting Tag for each Textfield in increasing order (say 1 - 4), below is the delegate handler to solve the issue.

它可以通过使用UITextField委托实现&通过按递增顺序为每个Textfield设置标记(例如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;
    }

#4


2  

I have taken one Hidden text field & four imageViews for that with two images. One for Blank and other for Bullet same as iOS default.

我已经为它取了一个隐藏的文本字段和四个图像视图,其中有两个图像。一个是空的,另一个是子弹的,和iOS默认一样。

Also set tags for four imageviews.

也为四个imageview设置标签。

On Load set Focus for Pin Code

对引脚代码的负载设置焦点

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

Then change imageview's images as per user input and only allow four characters

然后根据用户输入更改imageview的图像,只允许4个字符

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

After Four characters call function for generated PIN Code and store it in User Defaults same as iOS default PIN settings

4个字符后调用生成的PIN码函数,并将其存储在用户默认设置中,与iOS默认的PIN码设置相同

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

Here, you can again call StartPinCode method for re-confirming code.

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

Hopefully, it'll help you.
Thanks

希望它能对你有所帮助。谢谢

#5


2  

swift 2.3

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

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

#6


1  

Try this sample tutorial passcode lock

尝试这个示例教程密码锁定

ViewController.h

ViewController.h

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

ViewController.m

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

#7


1  

Provide the tag to the textfield like 1,2,3,4 and directly use it

将标记提供给textfield,如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

}

#8


0  

Just use TextFieldDelegate method and check the length of the TextField after every changes

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

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

#9


0  

Modified Anurag Soni's answer in Swift 3.

修改了Anurag Soni在Swift 3中的回答。

  • It assumes you have outlet collection named textFields and the text fields have ordered tags set
  • 它假定您有一个名为textFields的outlet集合,而文本字段已经设置了有序标记
  • It adds case when there's already some digit in text field and when user types something new - the digit is replaced
  • 当文本字段中已经有一些数字时,当用户输入一些新的数字时,就会添加大小写,数字就会被替换
  • Input is restricted to digits only
  • 输入仅限于数字。
  • It prevents from pasting more than one digit

    它防止粘贴超过一个数字

    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
    }
    

#10


-1  

try this : - For swift 3.0

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

converted Anurag Soni answer in swift 3.0

转换Anurag Soni回答在斯威夫特3.0

You just have to implement this method only.

你只需要实现这个方法。

#1


17  

You can change the text field like this by using the delegate function of the text field. Initially, you need to set the delegate and the tag of each text field.

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

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

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

Swift 4

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

}

#2


7  

use this code if you don't want work with tag and it works better then above

如果您不想使用标记,请使用此代码,并且它比上面更好地工作

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
    }

#3


3  

It can be achieve using UITextField delegate & by setting Tag for each Textfield in increasing order (say 1 - 4), below is the delegate handler to solve the issue.

它可以通过使用UITextField委托实现&通过按递增顺序为每个Textfield设置标记(例如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;
    }

#4


2  

I have taken one Hidden text field & four imageViews for that with two images. One for Blank and other for Bullet same as iOS default.

我已经为它取了一个隐藏的文本字段和四个图像视图,其中有两个图像。一个是空的,另一个是子弹的,和iOS默认一样。

Also set tags for four imageviews.

也为四个imageview设置标签。

On Load set Focus for Pin Code

对引脚代码的负载设置焦点

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

Then change imageview's images as per user input and only allow four characters

然后根据用户输入更改imageview的图像,只允许4个字符

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

After Four characters call function for generated PIN Code and store it in User Defaults same as iOS default PIN settings

4个字符后调用生成的PIN码函数,并将其存储在用户默认设置中,与iOS默认的PIN码设置相同

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

Here, you can again call StartPinCode method for re-confirming code.

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

Hopefully, it'll help you.
Thanks

希望它能对你有所帮助。谢谢

#5


2  

swift 2.3

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

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

#6


1  

Try this sample tutorial passcode lock

尝试这个示例教程密码锁定

ViewController.h

ViewController.h

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

ViewController.m

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

#7


1  

Provide the tag to the textfield like 1,2,3,4 and directly use it

将标记提供给textfield,如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

}

#8


0  

Just use TextFieldDelegate method and check the length of the TextField after every changes

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

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

#9


0  

Modified Anurag Soni's answer in Swift 3.

修改了Anurag Soni在Swift 3中的回答。

  • It assumes you have outlet collection named textFields and the text fields have ordered tags set
  • 它假定您有一个名为textFields的outlet集合,而文本字段已经设置了有序标记
  • It adds case when there's already some digit in text field and when user types something new - the digit is replaced
  • 当文本字段中已经有一些数字时,当用户输入一些新的数字时,就会添加大小写,数字就会被替换
  • Input is restricted to digits only
  • 输入仅限于数字。
  • It prevents from pasting more than one digit

    它防止粘贴超过一个数字

    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
    }
    

#10


-1  

try this : - For swift 3.0

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

converted Anurag Soni answer in swift 3.0

转换Anurag Soni回答在斯威夫特3.0

You just have to implement this method only.

你只需要实现这个方法。