Moving Onto The Next UITextField When 'Next' Is Tapped

30,551

Solution 1

You need to make your view controller the UITextField delegate, and implement the UITextField delegate method:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (textField == nameField) {
        [textField resignFirstResponder];
        [emailField becomeFirstResponder];
    } else if (textField == emailField) {
        // here you can define what happens
        // when user presses return on the email field
    }
    return YES;
}

Swift version:

func textFieldShouldReturn(textField: UITextField) -> Bool {
    if textField == nameField {
        textField.resignFirstResponder()
        emailField.becomeFirstResponder()
    } else if textField == emailField {
        // here you can define what happens
        // when user presses return on the email field
    }
    return true
}

You may also want to scroll your view for the emailField to become visible. If your view controller is an instance of UITableViewController, this should happen automatically. If not, you should read this Apple document, especially Moving Content That Is Located Under the Keyboard part.

Solution 2

Swift version of correct answer.

In my experience, you do not need to resignFirstResponder when switching textFields.

In this example, it's just your basic username and password textFields.

The keyboard "return key" in storyboard for username is set to "Next" and the one for password is set to "Done".

enter image description here

Then just connect the delegates for these two text fields and add this extension and you're pretty much done.

extension LoginViewController: UITextFieldDelegate {

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        if textField == textFieldPassword {
            self.view.endEditing(true)
        } else {
            textFieldPassword.becomeFirstResponder()
        }
        return true
    }

}

Solution 3

Additionally to @lawicko 's answer I often change the button text to give that final finishing touch (e.g. says next when there are more fields and then done when on the last):

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    BOOL isLastTextField = //.. your logic to figure out if the current text field is the last

    if (isLastTextField) {
        textField.returnKeyType = UIReturnKeyDone;
    } else {
        textField.returnKeyType = UIReturnKeyNext;
    }
}

Solution 4

A Swift 4 extension. Just pass the array of UITextFields and it will connect each one to the next until the last one which resigns the first responder (hides the keyboard):

extension UITextField {

    class func connectFields(fields: [UITextField]) {
        guard let last = fields.last else { return }

        // To reset the targets in case you call this method again to change the connected fields
        fields.forEach { $0.removeTarget(nil, action: nil, for: .editingDidEndOnExit) }

        for i in 0 ..< fields.count - 1 {
            fields[i].returnKeyType = .next
            fields[i].addTarget(fields[i + 1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)
        }

        last.returnKeyType = .continue
        last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)
    }
}

Solution 5

A more consistent and robust way is to use NextResponderTextField You can configure it totally from interface builder.

All you need to do is

  1. Set the class type of your UITextField to be NextResponderTextField enter image description here
  2. Then set the outlet of the nextResponderField to point to the next responder it can be anything UITextField or any UIResponder subclass. It can be also a UIButton and the library is smart enough to trigger the TouchUpInside event of the button only if it's enabled. enter image description here enter image description here

Here is the library in action:

enter image description here

Share:
30,551
Paul Morris
Author by

Paul Morris

Updated on November 15, 2020

Comments

  • Paul Morris
    Paul Morris over 3 years

    I have an iPad application which has a sign up form within it. The form is very basic and contains only two UITextFields which are for Name & Email address.

    The first TextField is for the candidates Name, When they enter their name in and press 'Next' on the keyboard I want this to automatically move to the next Email Address TextField to editing.

    Any idea how I can set the next button the keyboard to jump to the next keyboard?

    Thanks

  • Paul Morris
    Paul Morris over 12 years
    Thanks lawicko. The code worked perfectly with the email text field set to [email resignFirstResponder];. Thanks again.
  • Malloc
    Malloc over 11 years
    @lawicko The statement [textField resignFirstResponder]; in your code above is not important. While there still fields in the form, just move the becomeFirstResponder to the next field: [emailField becomeFirstResponder];
  • lawicko
    lawicko over 11 years
    @Malloc You are right, for the simple cases where the textField is not a subclass of the UITextField and doesn't do anything specific when the first responder status is relinquished. However, my code works good in all cases, including the more complicated ones. See here to learn why the resighFirstResponder may be overridden.
  • Michał Ziobro
    Michał Ziobro about 5 years
    I have to add something like this to make textFieldShouldReturn do not block Next button proper functioning extension FormViewController : UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.allControlEvents.contains(.editingDidEndOnExit) { textField.sendActions(for: .editingDidEndOnExit) return false } else { textField.resignFirstResponder() return true } } }