Get indexPath of UITextField in UITableViewCell with Swift

前端 未结 4 1145
庸人自扰
庸人自扰 2021-02-04 08:26

So, I\'m building a Detail View Controller App that presents a Table with a two-part cell: the label and the Text Field.

I\'m trying to retrieve the Text Field value and

相关标签:
4条回答
  • 2021-02-04 09:04

    You'll want to cast the first and second lines in your function, like this:

    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 returns a UIView, so you need to cast it to the type of view you expect.

    0 讨论(0)
  • 2021-02-04 09:04

    You can use tag property of UITableViewCell

    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
    }
    

    now in UITableViewCell

    func textFieldDidEndEditing(textField: UITextField!){
        let textFieldIndexPath = self.tag
    }
    
    0 讨论(0)
  • 2021-02-04 09:08

    While the currently accepted answer might work, it assumes a specific view hierarchy, which is not a reliable approach since it is prone to change.

    To get the indexPath from a UITextField that is inside a cell, it's much better to go with the following:

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

    This will continue to work independent of eventual changes to the view hierarchy.

    0 讨论(0)
  • 2021-02-04 09:25

    Using superview and typecasting isn't a preferred aaproach. The best practice is to use delegate pattern. If you have a textField in DemoTableViewCell which you are using in DemoTableViewController make a protocol DemoTableViewCellDelegate and assign delegate of DemoTableViewCell to DemoTableViewController so that viewcontroller is notified when eiditing ends in 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
      }
    }
    
    0 讨论(0)
提交回复
热议问题