Paul Morris
Paul Morris

Reputation: 1773

Moving Onto The Next UITextField When 'Next' Is Tapped

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

Upvotes: 38

Views: 31586

Answers (7)

Jonathan Cabrera
Jonathan Cabrera

Reputation: 1751

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

Upvotes: 5

lawicko
lawicko

Reputation: 7344

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.

Upvotes: 79

William T.
William T.

Reputation: 14341

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
    }

}

Upvotes: 10

mohamede1945
mohamede1945

Reputation: 7198

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

Upvotes: 5

davidrl1000
davidrl1000

Reputation: 361

Make an outlet for the textfield, then

viewController.h

(IBAction)textFieldDoneEditing:(id)sender;

viewController.m

(IBAction)textFieldDoneEditing:(id)sender {
    [textField resignFirstResponder];
    if (textField == nameField) {
        [emailField becomeFirstResponder];
    } 
} 

Make the relation between (show the connections inspector > Sent Events)didEndOnExit and textFieldDoneEditing

Upvotes: 0

Gank
Gank

Reputation: 4667

- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
    if (textField == self.textFieldName)
    {
        [self.textFieldName resignFirstResponder];
        [self.textFieldPassword becomeFirstResponder];
    }
    else if (textField == self.textFieldPassword)
    {
        [self.textFieldPassword resignFirstResponder];

        [self login:self];
    }

    return true;
}




@interface MLLoginViewController ()<UITextFieldDelegate>

@end

@implementation MLLoginViewController



- (void)viewDidLoad {
    [super viewDidLoad];
    self.textFieldName.delegate = self;
    self.textFieldPassword.delegate = self;

Upvotes: 0

Paul.s
Paul.s

Reputation: 38728

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

Upvotes: 10

Related Questions