使用Swift获取UITableViewCell中UITextField的indexPath

15

所以,我正在构建一个详细视图控制器应用程序,它呈现一个带有两部分单元格的表格:标签和文本字段。

我试图检索文本字段值并将其添加到数组中。 我尝试使用"textField.superview.superview"技术,但它没有起作用。

func textFieldDidEndEditing(textField: UITextField!){
    var cell: UITableViewCell = textField.superview.superview
    var table: UITableView = cell.superview.superview
    let textFieldIndexPath = table.indexPathForCell(cell)
}

Xcode编译失败并显示"UIView无法转换为UITableViewCell"和"到UITableView"。 该引用表有两个部分,分别有四行和两行。

提前感谢。

编辑: 在该函数的第二行加入".superview"。


2
你尝试过强制转换吗?在.superview.superview行的末尾添加"as UITableViewCell"。 - Connor
1
iOS 7改变了UITableViewCell的层次结构,something.superview.superview不再起作用。您需要使用[sender convertPoint:CGRectZero toView:self.tableView]来获取根点,然后转到NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootPoint];当然,您需要使用Swift代码来完成这个操作,但我不知道(只是展示算法)。 - Zhang
重复的问题:https://dev59.com/SmHVa4cB1Zd3GeqPkTTo#27938042 - Daniel Galasko
4个回答

29

虽然目前被接受的答案可能可行,但它假设了特定的视图层次结构,这不是一种可靠的方法,因为它容易改变。

要从单元格内部的UITextField获取indexPath,最好使用以下方法:

func textFieldDidEndEditing(textField: UITextField!){
    let pointInTable = textField.convert(textField.bounds.origin, to: self.tableView)
    let textFieldIndexPath = self.tableView.indexPathForRow(at: pointInTable)
    ...
}

无论视图层次结构最终如何更改,此功能将继续正常运行。


11

你需要在函数中将第一行和第二行进行转换,就像这样:

func textFieldDidEndEditing(textField: UITextField!){
    var cell: UITableViewCell = textField.superview.superview as UITableViewCell
    var table: UITableView = cell.superview as UITableView
    let textFieldIndexPath = table.indexPathForCell(cell)
}

superview返回一个UIView类型的对象,因此你需要将其转换为你所期望的视图类型。


现在它可以正确构建,但当模拟器运行“cell as UITableView”时,应用程序会崩溃。你能猜出问题出在哪里吗? - Nuno Casteleira
可能是因为单元格的父视图不是UITableView。您需要以不同的方式访问表视图。 - Connor
有什么建议吗?我对这个世界真的很陌生 ;) - Nuno Casteleira
https://dev59.com/HHNA5IYBdhLWcg3wC5Xh 可能会有所帮助。 - Connor
很有用。正是我在寻找的。 - Sami

9

使用superview和类型转换并不是首选方法。最佳实践是使用委托模式。如果您在DemoTableViewController中使用的DemoTableViewCell中有一个textField,请创建一个名为DemoTableViewCellDelegate的协议,并将DemoTableViewCell的委托分配给DemoTableViewController,以便在textfield编辑结束时通知视图控制器。

protocol DemoTableViewCellDelegate: class {
  func didEndEditing(onCell cell: DemoTableViewCell)
}

class DemoTableViewCell: UITableViewCell {
  @IBOutlet var textField: UITextField!

  weak var delegate: DemoTableViewCellDelegate?

  override func awakeFromNib() {
    super.awakeFromNib()
    textField.delegate = self
  }
}

extension DemoTableViewCell: UITextFieldDelegate {
  func textFieldDidEndEditing(_ textField: UITextField) {
    delegate.didEndEditing(onCell: self)
  }
}

class DemoTableViewController: UITableViewController {

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: DemoTableViewCell.self, for: indexPath)
    cell.delegate = self
    return cell
  }

}

extension DemoTableViewController: DemoTableViewCellDelegate {
  func didEndEditing(onCell cell: DemoTableViewCell) {
    //Indexpath for the cell in which editing have ended.
    //Now do whatever you want to do with the text and indexpath.
    let indexPath = tableView.indexPath(for: cell)
    let text = cell.textField.text
  }
}

-2
您可以使用UITableViewCelltag属性。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "UpdateTableViewCell", for: indexPath) as! UpdateTableViewCell

        cell.tag = indexPath.row
        cell.setCellData()

        return cell
}

现在在UITableViewCell

func textFieldDidEndEditing(textField: UITextField!){
    let textFieldIndexPath = self.tag
}

如果整个表视图中只有一个textField,并且不使用标签,则始终会返回0标签。标签仅在按钮操作中有用。 - Anurag Sharma

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