我如何通过iPhone键盘上的“下一步”按钮浏览所有的文本字段?

最后一个文本字段应该关闭键盘。

我已经设置了IB按钮(下一步/完成),但现在我卡住了。

我实现了textFieldShouldReturn动作,但现在下一步和完成按钮关闭键盘。


当前回答

这对我在Xamarin很有效。iOS / Monotouch。 将键盘按钮更改为Next,将控件传递给下一个UITextField,并将键盘隐藏在最后一个UITextField之后。

private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{
  foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField)))
  {
    (item as UITextField).ReturnKeyType = UIReturnKeyType.Next;
    (item as UITextField).ShouldReturn += (textField) =>
    {
        nint nextTag = textField.Tag + 1;
        var nextResponder = textField.Superview.ViewWithTag(nextTag);
        if (null != nextResponder)
            nextResponder.BecomeFirstResponder();
        else
            textField.Superview.EndEditing(true); 
            //You could also use textField.ResignFirstResponder(); 

        return false; // We do not want UITextField to insert line-breaks.
    };
  }
}

在ViewDidLoad里面你会有:

如果你的TextFields没有标签设置它现在:

txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...

只是一个电话

SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

其他回答

在Mac OS X的Cocoa中,你有下一个响应器链,在那里你可以询问文本字段下一个控件应该有焦点。这就是在文本字段之间进行标签操作的原因。但由于iOS设备没有键盘,只有触摸,所以这一概念没有在Cocoa touch的过渡中幸存下来。

这很容易做到,只要有两个假设:

所有“tabbable”UITextFields都在同一个父视图上。 它们的“制表符顺序”由tag属性定义。

假设你可以重写textFieldShouldReturn:如下:

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{
  NSInteger nextTag = textField.tag + 1;
  // Try to find next responder
  UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
  if (nextResponder) {
    // Found next responder, so set it.
    [nextResponder becomeFirstResponder];
  } else {
    // Not found, so remove keyboard.
    [textField resignFirstResponder];
  }
  return NO; // We do not want UITextField to insert line-breaks.
}

添加更多的代码,也可以忽略这些假设。

斯威夫特4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let nextTag = textField.tag + 1
    // Try to find next responder
    let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!

    if nextResponder != nil {
        // Found next responder, so set it
        nextResponder?.becomeFirstResponder()
    } else {
        // Not found, so remove keyboard
        textField.resignFirstResponder()
    }

    return false
}

如果文本字段的superview是一个UITableViewCell那么下一个responder将是

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!

这对我在Xamarin很有效。iOS / Monotouch。 将键盘按钮更改为Next,将控件传递给下一个UITextField,并将键盘隐藏在最后一个UITextField之后。

private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{
  foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField)))
  {
    (item as UITextField).ReturnKeyType = UIReturnKeyType.Next;
    (item as UITextField).ShouldReturn += (textField) =>
    {
        nint nextTag = textField.Tag + 1;
        var nextResponder = textField.Superview.ViewWithTag(nextTag);
        if (null != nextResponder)
            nextResponder.BecomeFirstResponder();
        else
            textField.Superview.EndEditing(true); 
            //You could also use textField.ResignFirstResponder(); 

        return false; // We do not want UITextField to insert line-breaks.
    };
  }
}

在ViewDidLoad里面你会有:

如果你的TextFields没有标签设置它现在:

txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...

只是一个电话

SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

当按下“Done”按钮时,一个非常简单的方法是:

在头文件中创建一个新的IBAction

- (IBAction)textFieldDoneEditing:(id)sender;

在实现文件(。M文件)添加如下方法:

- (IBAction)textFieldDoneEditing:(id)sender 
{ 
  [sender resignFirstResponder];
}

然后,当你来链接IBAction到文本框-链接到'Did End On Exit'事件。

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    txt_Input = [[ UITextField alloc] initWithFrame:CGRectMake(0, 10, 150, 30)];
    txt_Input.tag = indexPath.row+1;
    [self.array_Textfields addObject:txt_Input]; // Initialize mutable array in ViewDidLoad
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{

    int tag = ( int) textField.tag ;
    UITextField * txt = [  self.array_Textfields objectAtIndex:tag ] ;
    [ txt becomeFirstResponder] ;
    return YES ;
}

一个快速扩展,应用mxcl的答案,使这特别容易(适应swift 2.3由旅行者):

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for i in 0 ..< fields.count - 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), forControlEvents: .EditingDidEndOnExit)
    }
}

它很容易使用:

UITextField.connectFields([field1, field2, field3])

扩展将设置返回按钮为“下一步”为所有但最后一个字段和“完成”为最后一个字段,并转移焦点/解散键盘时,这些被轻敲。

Swift < 2.3

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for var i = 0; i < fields.count - 1; i += 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: "resignFirstResponder", forControlEvents: .EditingDidEndOnExit)
    }
}

斯威夫特3: 像这样使用-

UITextField.connectFields(fields: [field1, field2])

Extension:
    extension UITextField {
        class func connectFields(fields:[UITextField]) -> Void {
            guard let last = fields.last else {
                return
            }
            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 = .go
            last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)
        }
    }