当点击“下一个”时,如何移动到下一个UITextField?

38

我有一个iPad应用程序,其中包含一个注册表单。该表单非常基础,只包含两个UITextFields,分别用于姓名和电子邮件地址。

第一个TextField是候选人姓名,当他们输入姓名并按下键盘上的“下一个”时,我希望自动跳转到下一个电子邮件地址TextField进行编辑。

有什么办法可以将键盘上的下一个按钮设置为跳转到下一个键盘吗?

谢谢

7个回答

79

您需要将您的视图控制器设置为UITextField的代理,并实现UITextField代理方法:

- (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版本:

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
}

您可能还需要滚动视图以使emailField可见。 如果您的视图控制器是UITableViewController的实例,则应自动发生此操作。 如果不是,您应该阅读这份Apple文档,特别是移动位于键盘下方的内容部分。


谢谢lawicko。代码在将电子邮件文本字段设置为[email resignFirstResponder];时完美运行。再次感谢。 - Paul Morris
6
你的代码中的语句 [textField resignFirstResponder]; 并不重要。只要表单中还有其他字段,就将 becomeFirstResponder 移到下一个字段:[emailField becomeFirstResponder]; - Malloc
@Malloc 你说得对,对于那些textField不是UITextField的子类并且在第一响应者状态被放弃时不执行任何特定操作的简单情况来说,你是正确的。然而,我的代码适用于所有情况,包括更复杂的情况。请参见此处了解为什么可能需要重写resignFirstResponder - lawicko

10

除了 @lawicko 的回答外,我经常更改按钮文本以达到最后的完美效果(例如,在还有更多字段时显示“下一页”,在最后一个字段时显示“完成”):

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

10

Swift版本的正确答案。

根据我的经验,在切换文本字段时不需要调用resignFirstResponder。

在这个例子中,只有基本的用户名和密码文本字段。

Storyboard中用户名的键盘“return key”设置为“下一个”,密码的设置为“完成”。

enter image description here

然后只需连接这两个文本字段的代理并添加此扩展即可。

extension LoginViewController: UITextFieldDelegate {

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

}

5

一个 Swift 4 的拓展。只需传入 UITextFields 数组,它将把每个文本框连接到下一个,直到最后一个文本框放弃第一响应者(隐藏键盘):

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

我必须添加以下内容,以使textFieldShouldReturn不会阻止Next按钮的正常功能。 扩展FormViewController:UITextFieldDelegate {func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.allControlEvents.contains(.editingDidEndOnExit) { textField.sendActions(for: .editingDidEndOnExit) return false } else { textField.resignFirstResponder() return true } }} - Michał Ziobro

5
一种更一致和强大的方法是使用NextResponderTextField。你可以完全从界面构建器中进行配置。
你需要做的只是:
  1. 将你的UITextField的类类型设置为NextResponderTextFieldenter image description here
  2. 然后将nextResponderField的输出口指向下一个响应器,它可以是任何UITextField或任何UIResponder子类。它还可以是一个UIButton,如果启用,则库足够智能,只会触发按钮的TouchUpInside事件。 enter image description here enter image description here
这是该库的操作示例: enter image description here

0
创建一个文本框的输出口,然后。

viewController.h

(IBAction)textFieldDoneEditing:(id)sender;

viewController.m

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

建立(show the connections inspector > Sent Events)didEndOnExit和textFieldDoneEditing之间的关联


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接