ios 如何以编程方式在swift ios中自动将光标从一个文本字段移动到另一个文本字段?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35331839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:28:33  来源:igfitidea点击:

How to move cursor from one text field to another automatically in swift ios programmatically?

iosswiftuitextfielddelegate

提问by Rakesh Mohan

    func textFieldDidBeginEditing(textField: UITextField) {
    scrlView.setContentOffset(CGPointMake(0, textField.frame.origin.y-70), animated: true)


    if(textField == firstDigit){

        textField.becomeFirstResponder()
        secondDigit.resignFirstResponder()
    }


    else if(textField == secondDigit){

        textField.becomeFirstResponder()
        thirdDigit.resignFirstResponder()
    }

    else if(textField == thirdDigit){
        //textField.becomeFirstResponder()
        fourthDigit.becomeFirstResponder()
    }

I am using four textfields for OTP entry in which only one number can be entered at a time. After entering the number I need to move the cursor automatically to next textfield.

我正在使用四个文本字段进行 OTP 输入,其中一次只能输入一个数字。输入数字后,我需要将光标自动移动到下一个文本字段。

回答by Hamza Ansari

Set textField delegate and add target:

设置 textField 委托并添加目标:

override func viewDidLoad() {
        super.viewDidLoad()

        first.delegate = self
        second.delegate = self
        third.delegate = self
        fourth.delegate = self


        first.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
        second.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
        third.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
        fourth.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
    }

Now when text changes change textField

现在当文本更改更改 textField

func textFieldDidChange(textField: UITextField){

    let text = textField.text

    if text?.utf16.count >= 1{
        switch textField{
        case first:
            second.becomeFirstResponder()
        case second:
            third.becomeFirstResponder()
        case third:
            fourth.becomeFirstResponder()
        case fourth:
            fourth.resignFirstResponder()
        default:
            break
        }
    }else{

    }
}

And lastly when user start editing clear textField

最后当用户开始编辑 clear textField 时

extension ViewController: UITextFieldDelegate{
    func textFieldDidBeginEditing(textField: UITextField) {
        textField.text = ""
    }
}

回答by Anup Gupta

Solution For Swift 4+

Swift解决方案4+

In This solution, You will go to next Field. And When You Press Erase will come at previous text field.

在此解决方案中,您将转到下一个字段。当您按下擦除时,将出现在上一个文本字段中。

Step 1:Set Selector for Text Field

步骤 1:为文本字段设置选择器

override func viewDidLoad() {
        super.viewDidLoad()

        otpTextField1.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
        otpTextField2.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
        otpTextField3.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
        otpTextField4.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)

    }

Step 2:Now We will handle move next text Field and Erase text Field.

第 2 步:现在我们将处理移动下一个文本字段和擦除文本字段。

@objc func textFieldDidChange(textField: UITextField){
        let text = textField.text
        if  text?.count == 1 {
            switch textField{
            case otpTextField1:
                otpTextField2.becomeFirstResponder()
            case otpTextField2:
                otpTextField3.becomeFirstResponder()
            case otpTextField3:
                otpTextField4.becomeFirstResponder()
            case otpTextField4:
                otpTextField4.resignFirstResponder()
            default:
                break
            }
        }
        if  text?.count == 0 {
            switch textField{
            case otpTextField1:
                otpTextField1.becomeFirstResponder()
            case otpTextField2:
                otpTextField1.becomeFirstResponder()
            case otpTextField3:
                otpTextField2.becomeFirstResponder()
            case otpTextField4:
                otpTextField3.becomeFirstResponder()
            default:
                break
            }
        }
        else{

        }
    }

Important Note:Don't Forget To set Delegate.

重要提示:不要忘记设置委托。

回答by santhosh kumar

Swift 3 code to move the cursor from one field to another automatically in OTP(One Time Password) fields.

Swift 3 代码可在 OTP(一次性密码)字段中自动将光标从一个字段移动到另一个字段。

    //Add all outlet in your code. 
    @IBOutlet weak var otpbox1: UITextField!
    @IBOutlet weak var otpbox2: UITextField!
    @IBOutlet weak var otpbox3: UITextField!
    @IBOutlet weak var otpbox4: UITextField!
    @IBOutlet weak var otpbox5: UITextField!
    @IBOutlet weak var otpbox6: UITextField!
    // Add the delegate in viewDidLoad
    func viewDidLoad() {
        super.viewDidLoad()
        otpbox1?.delegate = self
        otpbox2?.delegate = self
        otpbox3?.delegate = self
        otpbox4?.delegate = self
        otpbox5?.delegate = self
        otpbox6?.delegate = self
    }
    func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
        // Range.length == 1 means,clicking backspace
    if (range.length == 0){
        if textField == otpbox1 {
            otpbox2?.becomeFirstResponder()
        }
        if textField == otpbox2 {
            otpbox3?.becomeFirstResponder()
        }
        if textField == otpbox3 {
            otpbox4?.becomeFirstResponder()
        }
        if textField == otpbox4 {
            otpbox5?.becomeFirstResponder()
        }
        if textField == otpbox5 {
            otpbox6?.becomeFirstResponder()
        }
        if textField == otpbox6 {
            otpbox6?.resignFirstResponder() /*After the otpbox6 is filled we capture the All the OTP textField and do the server call. If you want to capture the otpbox6 use string.*/
            let otp = "\((otpbox1?.text)!)\((otpbox2?.text)!)\((otpbox3?.text)!)\((otpbox4?.text)!)\((otpbox5?.text)!)\(string)"
        }
        textField.text? = string
        return false
    }else if (range.length == 1) {
            if textField == otpbox6 {
                otpbox5?.becomeFirstResponder()
            }
            if textField == otpbox5 {
                otpbox4?.becomeFirstResponder()
            }
            if textField == otpbox4 {
                otpbox3?.becomeFirstResponder()
            }
            if textField == otpbox3 {
                otpbox2?.becomeFirstResponder()
            }
            if textField == otpbox2 {
                otpbox1?.becomeFirstResponder()
            }
            if textField == otpbox1 {
                otpbox1?.resignFirstResponder()
            }
            textField.text? = ""
            return false
    }
    return true
    }

回答by Priyanka Jadhav

Firstly we'll need to set the tag for the UITextField;

首先,我们需要为 UITextField 设置标签;

func textFieldShouldReturnSingle(_ textField: UITextField , newString : String)
{
    let nextTag: Int = textField.tag + 1

    let nextResponder: UIResponder? = textField.superview?.superview?.viewWithTag(nextTag)
    textField.text = newString
    if let nextR = nextResponder
    {
        // Found next responder, so set it.
        nextR.becomeFirstResponder()
    }
    else
    {
        // Not found, so remove keyboard.
        textField.resignFirstResponder()
    }
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let newString = ((textField.text)! as NSString).replacingCharacters(in: range, with: string)

    let newLength = newString.characters.count

    if newLength == 1 {
        textFieldShouldReturnSingle(textField , newString : newString)
        return false
    }

    return true
}

Note: The UITextField takes only one character in number format, which is in OTP format.

注意:UITextField 只需要一个数字格式的字符,即OTP 格式。

回答by Lance Samaria

This is similar to how UberEatshas their otp fields. You can just copy and paste this into a file and run it to see how it works. But don't forget to add the MyTextField classor it won't work.

这类似于UberEats的 otp 字段。您只需将其复制并粘贴到一个文件中,然后运行它以查看它是如何工作的。但是不要忘记添加MyTextField 类,否则它将不起作用。

If you want it to automatically to move to the next textfield after a number is entered and still be able to move backwards if the back button is pressed WHILE the textField is empty this will help you.

如果您希望它在输入数字后自动移动到下一个文本字段,并且如果在文本字段为空时按下后退按钮仍然能够向后移动,这将对您有所帮助。

Like the very first thing I said, this is similarto how UberEats has their sms textFields working. You can't just randomly press a textField and select it. Using this you can only move forward and backwards. The ux is subjective but if Uber uses it the ux must be valid. I say it's similar because they also have a gray box covering the textField so I'm not sure what's going on behind it. This was the closest I could get.

就像我说的第一件事一样,这类似于UberEats 的 sms textFields 工作方式。您不能只是随机按下一个 textField 并选择它。使用这个你只能向前和向后移动。用户体验是主观的,但如果优步使用它,用户体验必须是有效的。我说它是相似的,因为它们也有一个覆盖 textField 的灰色框,所以我不确定它后面发生了什么。这是我能得到的最接近的。

First your going to have to subclass UITextField using this answerto detect when the backspace button is pressed. When the back button is pressed your going to erase everything inside that field AND the previous field then jump to the previous field.

首先,您必须使用此答案对UITextField进行子类化,以检测何时按下退格按钮。当按下后退按钮时,您将删除该字段和前一个字段内的所有内容,然后跳转到前一个字段。

Second your going to have to prevent the user from being able to select the left side of the cursor once a char is inside the textField using this answer. You override the method in the same subClass from the first step.

其次,一旦字符位于 textField 内,您将不得不使用此答案防止用户选择光标的左侧。您从第一步覆盖同一子类中的方法。

Third you need to detect which textField is currently active using this answer

第三,您需要使用此答案检测当前哪个 textField 处于活动状态

Fourth your going to have to run some checks inside func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Boolusing this YouTube tutorial. I added some things to his work.

第四,您必须func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool使用此 YouTube 教程在内部运行一些检查。我在他的作品中添加了一些东西。

I'm doing everything programmatically so you can copy and paste the entire code into a project and run it

我正在以编程方式完成所有工作,因此您可以将整个代码复制并粘贴到项目中并运行它

First create a subClass of UITextField and name it MyTextField:

首先创建一个 UITextField 的子类并将其命名为MyTextField

protocol MyTextFieldDelegate: class {
    func textFieldDidDelete()
}

// 1. subclass UITextField and create protocol for it to know when the backButton is pressed
class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate? // make sure to declare this as weak to prevent a memory leak/retain cycle

    override func deleteBackward() {
        super.deleteBackward()
        myDelegate?.textFieldDidDelete()
    }

    // when a char is inside the textField this keeps the cursor to the right of it. If the user can get on the left side of the char and press the backspace the current char won't get deleted
    override func closestPosition(to point: CGPoint) -> UITextPosition? {
        let beginning = self.beginningOfDocument
        let end = self.position(from: beginning, offset: self.text?.count ?? 0)
        return end
    }
}

Second inside the class with the OTP textfields, set the class to use the UITextFieldDelegate and the MyTextFieldDelegate, then create a class property and name it activeTextField. When whichever textField becomes active inside textFieldDidBeginEditingyou set the activeTextFieldto that. In viewDidLoad set all the textFields to use both delegates.

其次,在带有 OTP 文本字段的类中,将类设置为使用 UITextFieldDelegate 和 MyTextFieldDelegate,然后创建一个类属性并将其命名为activeTextField。当其中的任何 textField 变为活动状态时,textFieldDidBeginEditing您都将其activeTextField设置为该值。在 viewDidLoad 中,将所有 textField 设置为使用两个委托。

Make sure the First otpTextField is ENABLED and the second, third, and fourth otpTextFields are ALL initially DIASABLED

确保第一个 otpTextField 已启用,并且第二个、第三个和第四个 otpTextField 最初都已禁用

import UIKit

// 2. set the class to BOTH Delegates
class ViewController: UIViewController, UITextFieldDelegate, MyTextFieldDelegate {

    let staticLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 17)
        label.text = "Enter the SMS code sent to your phone"
        return label
    }()

    // 3. make each textField of type MYTextField
    let otpTextField1: MyTextField = {
        let textField = MyTextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.font = UIFont.systemFont(ofSize: 25)
        textField.autocorrectionType = .no
        textField.keyboardType = .numberPad
        textField.textAlignment = .center
        // **important this is initially ENABLED
        return textField
    }()

    let otpTextField2: MyTextField = {
        let textField = MyTextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.font = UIFont.systemFont(ofSize: 25)
        textField.autocorrectionType = .no
        textField.keyboardType = .numberPad
        textField.textAlignment = .center
        textField.isEnabled = false // **important this is initially DISABLED
        return textField
    }()

    let otpTextField3: MyTextField = {
        let textField = MyTextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.font = UIFont.systemFont(ofSize: 25)
        textField.autocorrectionType = .no
        textField.keyboardType = .numberPad
        textField.textAlignment = .center
        textField.isEnabled = false // **important this is initially DISABLED
        return textField
    }()

    let otpTextField4: MyTextField = {
        let textField = MyTextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.font = UIFont.systemFont(ofSize: 25)
        textField.autocorrectionType = .no
        textField.keyboardType = .numberPad
        textField.textAlignment = .center
        textField.isEnabled = false // **important this is initially DISABLED
        return textField
    }()

    // 4. create this property to know which textField is active. Set it in step 8 and use it in step 9
    var activeTextField = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        // 5. set the regular UItextField delegate to each textField
        otpTextField1.delegate = self
        otpTextField2.delegate = self
        otpTextField3.delegate = self
        otpTextField4.delegate = self

        // 6. set the subClassed textField delegate to each textField
        otpTextField1.myDelegate = self
        otpTextField2.myDelegate = self
        otpTextField3.myDelegate = self
        otpTextField4.myDelegate = self

        configureAnchors()

        // 7. once the screen appears show the keyboard 
        otpTextField1.becomeFirstResponder()
    }

// 8. when a textField is active set the activeTextField property to that textField
func textFieldDidBeginEditing(_ textField: UITextField) {

    activeTextField = textField
}

// 9. when the backButton is pressed, the MyTextField delegate will get called. The activeTextField will let you know which textField the backButton was pressed in. Depending on the textField certain textFields will become enabled and disabled.
func textFieldDidDelete() {

    if activeTextField == otpTextField1 {
        print("backButton was pressed in otpTextField1")
        // do nothing
    }

    if activeTextField == otpTextField2 {
        print("backButton was pressed in otpTextField2")
        otpTextField2.isEnabled = false
        otpTextField1.isEnabled = true
        otpTextField1.becomeFirstResponder()
        otpTextField1.text = ""
    }

    if activeTextField == otpTextField3 {
        print("backButton was pressed in otpTextField3")
        otpTextField3.isEnabled = false
        otpTextField2.isEnabled = true
        otpTextField2.becomeFirstResponder()
        otpTextField2.text = ""
    }

    if activeTextField == otpTextField4 {
        print("backButton was pressed in otpTextField4")
        otpTextField4.isEnabled = false
        otpTextField3.isEnabled = true
        otpTextField3.becomeFirstResponder()
        otpTextField3.text = ""
    }
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let text = textField.text {

        // 10. when the user enters something in the first textField it will automatically adjust to the next textField and in the process do some disabling and enabling. This will proceed until the last textField
        if (text.count < 1) && (string.count > 0) {

            if textField == otpTextField1 {
                otpTextField1.isEnabled = false
                otpTextField2.isEnabled = true
                otpTextField2.becomeFirstResponder()
            }

            if textField == otpTextField2 {
                otpTextField2.isEnabled = false
                otpTextField3.isEnabled = true
                otpTextField3.becomeFirstResponder()
            }

            if textField == otpTextField3 {
                otpTextField3.isEnabled = false
                otpTextField4.isEnabled = true
                otpTextField4.becomeFirstResponder()
            }

            if textField == otpTextField4 {
                // do nothing or better yet do something now that you have all four digits for the sms code. Once the user lands on this textField then the sms code is complete
            }

            textField.text = string
            return false

        } // 11. if the user gets to the last textField and presses the back button everything above will get reversed
        else if (text.count >= 1) && (string.count == 0) {

            if textField == otpTextField2 {
                otpTextField2.isEnabled = false
                otpTextField1.isEnabled = true
                otpTextField1.becomeFirstResponder()
                otpTextField1.text = ""
            }

            if textField == otpTextField3 {
                otpTextField3.isEnabled = false
                otpTextField2.isEnabled = true
                otpTextField2.becomeFirstResponder()
                otpTextField2.text = ""
            }

            if textField == otpTextField4 {
                otpTextField4.isEnabled = false
                otpTextField3.isEnabled = true
                otpTextField3.becomeFirstResponder()
                otpTextField3.text = ""
            }

            if textField == otpTextField1 {
                // do nothing
            }

            textField.text = ""
            return false

        } // 12. after pressing the backButton and moving forward again you will have to do what's in step 10 all over again
        else if text.count >= 1 {

            if textField == otpTextField1 {
                otpTextField1.isEnabled = false
                otpTextField2.isEnabled = true
                otpTextField2.becomeFirstResponder()
            }

            if textField == otpTextField2 {
                otpTextField2.isEnabled = false
                otpTextField3.isEnabled = true
                otpTextField3.becomeFirstResponder()
            }

            if textField == otpTextField3 {
                otpTextField3.isEnabled = false
                otpTextField4.isEnabled = true
                otpTextField4.becomeFirstResponder()
            }

            if textField == otpTextField4 {
                // do nothing or better yet do something now that you have all four digits for the sms code. Once the user lands on this textField then the sms code is complete
            }

            textField.text = string
            return false
        }
    }
    return true
}

//**Optional** For a quick setup use this below. Here is how to add a gray line to the textFields and here are the anchors:
    // if your app supports portrait and horizontal your going to have to make some adjustments to this every time the phone rotates
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        addBottomLayerTo(textField: otpTextField1)
        addBottomLayerTo(textField: otpTextField2)
        addBottomLayerTo(textField: otpTextField3)
        addBottomLayerTo(textField: otpTextField4)
    }

    // this adds a lightGray line at the bottom of the textField
    func addBottomLayerTo(textField: UITextField) {
        let layer = CALayer()
        layer.backgroundColor = UIColor.lightGray.cgColor
        layer.frame = CGRect(x: 0, y: textField.frame.height - 2, width: textField.frame.width, height: 2)
        textField.layer.addSublayer(layer)
    }

    func configureAnchors() {

        view.addSubview(staticLabel)

        view.addSubview(otpTextField1)
        view.addSubview(otpTextField2)
        view.addSubview(otpTextField3)
        view.addSubview(otpTextField4)

        let width = view.frame.width / 5

        staticLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 15).isActive = true
        staticLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
        staticLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true

        // textField 1
        otpTextField1.topAnchor.constraint(equalTo: staticLabel.bottomAnchor, constant: 10).isActive = true
        otpTextField1.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
        otpTextField1.widthAnchor.constraint(equalToConstant: width).isActive = true
        otpTextField1.heightAnchor.constraint(equalToConstant: width).isActive = true

        // textField 2
        otpTextField2.topAnchor.constraint(equalTo: staticLabel.bottomAnchor, constant: 10).isActive = true
        otpTextField2.leadingAnchor.constraint(equalTo: otpTextField1.trailingAnchor, constant: 10).isActive = true
        otpTextField2.widthAnchor.constraint(equalTo: otpTextField1.widthAnchor).isActive = true
        otpTextField2.heightAnchor.constraint(equalToConstant: width).isActive = true

        // textField 3
        otpTextField3.topAnchor.constraint(equalTo: staticLabel.bottomAnchor, constant: 10).isActive = true
        otpTextField3.leadingAnchor.constraint(equalTo: otpTextField2.trailingAnchor, constant: 10).isActive = true
        otpTextField3.widthAnchor.constraint(equalTo: otpTextField1.widthAnchor).isActive = true
        otpTextField3.heightAnchor.constraint(equalToConstant: width).isActive = true

        // textField 4
        otpTextField4.topAnchor.constraint(equalTo: staticLabel.bottomAnchor, constant: 10).isActive = true
        otpTextField4.leadingAnchor.constraint(equalTo: otpTextField3.trailingAnchor, constant: 10).isActive = true
        otpTextField4.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
        otpTextField4.widthAnchor.constraint(equalTo: otpTextField1.widthAnchor).isActive = true
        otpTextField4.heightAnchor.constraint(equalToConstant: width).isActive = true
     }
}

enter image description here

在此处输入图片说明

This is separate from the answer above but if you need to add multiple characters to each otpTextFieldthen follow this answer.

这是从上面的答案分开,但如果你需要添加多个字符到每个otpTextField然后按照这个答案

回答by Gangireddy Rami Reddy

Objective c and Swift 4.2 to move the cursor from one field to another automatically in OTP(One Time Password) fields

Objective c 和 Swift 4.2 在 OTP(一次性密码)字段中自动将光标从一个字段移动到另一个字段

Here i am taking one view controller view controller screen design stackview inside textfileds[![][1]]1

在这里,我正在使用一个视图控制器 在 textfileds[![][1] 中查看控制器屏幕设计 stackview] 1

Then give the Tag values for each TextFiled.Those related reference images are shown below Enter tag value for first textfiled -->1,2ndTextfiled ---->2,3rd TextFiled --->3   4rth TextFiled---->4

然后给出每个TextFiled的Tag值。那些相关的参考图片如下所示 输入第一个文本文件的标签值 -->1,2ndTextfiled ---->2,3rd TextFiled --->3 4rth TextFiled---->4

enter image description here

在此处输入图片说明

Enter tag value for first textfiled --> 1,2ndTextfiled ---->2,3rd TextFiled --->3 4rth TextFiled---->4

输入第一个文本文件的标签值 --> 1,2ndTextfiled ---->2,3rd TextFiled --->3 4rth TextFiled---->4

Then assign Textfiled Delegates and write below code and see the magic

然后分配 Textfiled Delegates 并编写下面的代码并查看魔术

 - (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)){
    // 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;

}

}

swift4.2 version code

swift4.2 版本代码

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {



    if textField.text!.count < 1 && string.count > 0 {
        let tag = textField.tag + 1;
        let nextResponder = textField.superview?.viewWithTag(tag)

        if   (nextResponder != nil){
            textField.resignFirstResponder()

        }
        textField.text = string;
        if (nextResponder != nil){
            nextResponder?.becomeFirstResponder()

        }
        return false;


    }else if (textField.text?.count)! >= 1 && string.count == 0 {
        let prevTag = textField.tag - 1
        let prevResponser = textField.superview?.viewWithTag(prevTag)
          if (prevResponser != nil){
            textField.resignFirstResponder()
        }
        textField.text = string
        if (prevResponser != nil){
            prevResponser?.becomeFirstResponder()

        }
         return false
    }


    return true;

}

回答by Sureshkumar Linganathan

Use textFieldShouldBeginEditing method

使用 textFieldShouldBeginEditing 方法

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
   scrlView.setContentOffset(CGPointMake(0, textField.frame.origin.y-70), 
 animated:true)

   if(textField == firstDigit){

      textField.becomeFirstResponder()
     secondDigit.resignFirstResponder()
   }
   else if(textField == secondDigit){

    textField.becomeFirstResponder()
    thirdDigit.resignFirstResponder()
    }
    else if(textField == thirdDigit){
    //textField.becomeFirstResponder()
    fourthDigit.becomeFirstResponder()
    }
   return true;
}

回答by Ajay Singh Thakur

**call from UITextfieldDelegate function and make next text field the first responder and no need to add target and remember to set delegates of all text fields in viewDidLoad **

**从 UITextfieldDelegate 函数调用并使下一个文本字段成为第一响应者,无需添加目标并记住在 viewDidLoad 中设置所有文本字段的委托 **

            extension ViewController : UITextFieldDelegate {


            func textFieldShouldReturn(textField: UITextField) -> Bool {

              nextTextFieldToFirstResponder(textField)

              return true;
            }




          func nextTextFieldToFirstResponder(textField: UITextField) {

            if textField == emailTextField
            {
              self.firstNameTextField.becomeFirstResponder()
            }
            else if   textField == firstNameTextField {

              self.lastNameTextField.becomeFirstResponder()
            }

            else if  textField == lastNameTextField {

              self.passwordTextField.becomeFirstResponder()
            }

            else if textField == passwordTextField {

              self.confirmPassTextField.becomeFirstResponder()
            }

            else if textField == confirmPassTextField {
              self.confirmPassTextField.resignFirstResponder()

            }

          }

回答by BHUVANESH MOHANKUMAR

I have tried many codes and finally this worked for me in Swift 3.0 Latest [March 2017]

我尝试了很多代码,最后这在 Swift 3.0 最新版 [2017 年 3 月] 中对我有用

The "ViewController" class should inherited the "UITextFieldDelegate" for making this code working.

“ViewController”类应该继承“UITextFieldDelegate”以使此代码工作。

class ViewController: UIViewController,UITextFieldDelegate 

Add the Text field with the Proper Tag nuber and this tag number is used to take the control to appropriate text field based on incremental tag number assigned to it.

添加带有正确标签编号的文本字段,此标签编号用于根据分配给它的增量标签编号将控件带到适当的文本字段。

override func viewDidLoad() {

 userNameTextField.delegate = self

        userNameTextField.tag = 0

        userNameTextField.returnKeyType = UIReturnKeyType.next

        passwordTextField.delegate = self

        passwordTextField.tag = 1


        passwordTextField.returnKeyType = UIReturnKeyType.go

}

In the above code, the "returnKeyType = UIReturnKeyType.next" where will make the Key pad return key to display as "Next" you also have other options as "Join/Go" etc, based on your application change the values.

在上面的代码中,“returnKeyType = UIReturnKeyType.next”将使键盘返回键显示为“Next”,您还有其他选项如“Join/Go”等,根据您的应用程序更改值。

This "textFieldShouldReturn" is a method of UITextFieldDelegate controlled and here we have next field selection based on the Tag value incrementation

这个“textFieldShouldReturn”是 UITextFieldDelegate 控制的一个方法,这里我们有基于 Tag 值增量的下一个字段选择

func textFieldShouldReturn(_ textField: UITextField) -> Bool

    {

        if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {

            nextField.becomeFirstResponder()

        } else {

            textField.resignFirstResponder()

            return true;

        }

        return false

    }

回答by Arjun Patel

Here I was take 4 TextField

这里我拿了 4 个 TextField

@IBOutlet var txtOtp: [BottomBorderTextField]!

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    defer{
        if !string.isEmpty {
            textField.text = string
            textField.resignFirstResponder()
            if let index = self.txtOtp.index(where:{##代码## === textField}) {
                if index < 3 {
                  self.txtOtp[index + 1].becomeFirstResponder()
                }
            }
        }
    }
    return true
}