0

In tableview, on the cells there are buttons in it, need to get the index of tableview means, which index cell's button is clicked. So, not able to implement it in swift 5. So far tried is but this give me wrong value.

let position: CGPoint = sender.convert(CGPoint.zero, to: organizationsTableView)
if let indexPath = organizationsTableView.indexPathForRow(at: position) {
    print(indexPath)
}
iPhone 7
  • 1,731
  • 1
  • 27
  • 63
  • 1
    A pretty *swifty* way are callback closures. They are more efficient than tags or protocols or view geometry math. – vadian Sep 25 '19 at 13:01
  • Please post an answer using my code or any other better way of achieving this – iPhone 7 Sep 25 '19 at 13:03

3 Answers3

2

1) In your Custom cell add closure:

class YoutuberTableViewCell: UITableViewCell {

    var buttonAction : (() -> ())?


    @IBAction func buttonTapped(_ sender: UIButton) {

        buttonAction?()
    }

}

2) In your cellForRowAt implement the closure

extension ViewController : UITableViewDataSource {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! YoutuberTableViewCell

        cell.buttonAction = { [unowned self] in
            let selectedIndexPath = indexPath.row
        }

        return cell
    }

}
Prakash Shaiva
  • 1,047
  • 8
  • 12
0

add indexPath.row as a tag to the button inside tableViewCell

button.tag = indexPath.row
button.addTarget(self, action: #selector(buttonClickMethod(_:)), for: .touchUpInside)

If you are using xib then you can add tag to the button from Attribute Inspector

Inside buttonClickMethod you can access the index like this

func buttonClickMethod(_ sender: UIButton){
   let index = sender.tag
}
Sumeet.Jain
  • 1,533
  • 9
  • 26
0

A callback closure is the most efficient way in Swift.

However only capturing the index path in cellForRowAt like in Prakash Shaiva's answer is not sufficient if cells can be inserted, deleted or moved. In this particular case you have to pass the cell

class MyTableViewCell: UITableViewCell {

    var callback : ((UITableViewCell) -> Void)?

    @IBAction func push(_ sender: UIButton) {
        callback?(self)
    }   
}

and get the current index path for the cell in the closure

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyIdentidier", for: indexPath) as! MyTableViewCell
    cell.callback = { currentCell in
        let currentIndexPath = tableView.indexPath(for: currentCell)!
    }
    return cell
}
vadian
  • 274,689
  • 30
  • 353
  • 361