问题描述
我在 tableview 的故事板中放置了一个 UITextField,并使用代码创建了多个文本字段(4 个)。
我的问题是按键盘上的返回键时我无法转到第二个 uitextfield。我在tableview单元格中使用了下面的代码
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
}
解决方法
您的表格中有 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
方法中获取下一个单元格并设置下一个单元格 textField 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
}