当对所有文本字段使用一个公共文本字段时如何转到下一个文本字段?

How to goto next textfield when using one common textfield for all textfield?

我在 tableview 中的故事板中放置了一个 UITextField,并使用代码创建了多个文本字段(4 个)。

我的问题是按键盘上的 return 键时无法转到第二个 uitextfield。我在 tableview cell

中使用了下面的代码
func textFieldShouldReturn(textField: UITextField) -> Bool {
    let nextTag: NSInteger = textField.tag + 1

    let nextResponder: UIResponder = textField.superview!.viewWithTag(nextTag)!
    if (nextResponder != nil) {

        nextResponder.becomeFirstResponder()
    } else {
      
        textField.resignFirstResponder()
    }
    return false 
}

您的 table 中有 4 行,其中每个单元格都有一个 UITextField

所以您尝试使用的代码是:

textField.superview!.viewWithTag(nextTag)!

不起作用,因为 textField.superview 是包含该文本字段的单元格的 contentView

一种方法是使用闭包,让您的单元格告诉控制器用户点击了 Return,然后让控制器处理将下一行的文本字段设置为第一响应者。

这是一个非常简单的示例,说明您可能希望如何实现它:

class ResponderCell: UITableViewCell, UITextFieldDelegate {
    
    @IBOutlet var textField: UITextField!
    
    var returnClosure: ((String, UITableViewCell)->())?
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {

        textField.resignFirstResponder()
        
        // tell our table view controller
        returnClosure?(textField.text ?? "", self)
        
        return false

    }
    
}

class ResponderTableViewController: UITableViewController {
    var myData: [String] = [
        "One",
        "Two",
        "Three",
        "Four",
    ]
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "rCell", for: indexPath) as! ResponderCell
        
        c.textField.text = myData[indexPath.row]
        
        c.returnClosure = { [weak self, weak tableView] str, c in
            // make sure we're safely accessing these objects
            guard let self = self,
                  let tableView = tableView,
                  let pth = tableView.indexPath(for: c)
            else {
                return
            }

            // update data array with textField's text
            self.myData[pth.row] = str

            // increment the row
            let nextIndexPath = IndexPath(row: pth.row + 1, section: pth.section)

            // if we can get the next cell...
            if let nextCell = self.tableView.cellForRow(at: nextIndexPath) as? ResponderCell {
                // set it's textField to first responder
                nextCell.textField.becomeFirstResponder()
            }
        }

        return c
    }
    
}

首先在 cellForRowAtIndexPath 方法中用当前行设置 textField 标签。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
        
        cell.textField.tag = indexPath.row

    return cell
    }

之后在 textFieldShouldReturn 方法中获取下一个单元格并设置下一个单元格文本字段 firstResponder.

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let nexttag = textField.tag + 1
    if nexttag < tableView.numberOfRows(inSection: 0) {
        let nextIndexPath = IndexPath(row: nexttag, section: 0)
        if let cell = tableView.cellForRow(at: nextIndexPath) as? MyCell{
            cell.textfield.becomeFirstResponder()
            tableView.scrollToRow(at: nextIndexPath, at: .none, animated: true)
        }
    } else {
        textField.resignFirstResponder()
    }
    return false
}