1

I have table view and cell with one button. I want when I click button in which row, the current row selected. (I mean the row button is in it).

I write below code but it select just first row:

@IBAction func btnShowAds(_ sender: Any) {

    let indexPath = IndexPath(row: 0, section: 0)
    tblMain.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
    tblMain.delegate?.tableView!(tblMain, didSelectRowAt: indexPath)
}

what is solution

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
jytt
  • 13
  • 1
  • 3
  • Possible duplicate of [How can I get indexPath.row in cell.swift](https://stackoverflow.com/questions/40437550/how-can-i-get-indexpath-row-in-cell-swift) – matiastofteby Sep 17 '17 at 15:02

1 Answers1

3

You have a few possibilities here. One of them and the easiest, would be using tags.

To you give a complete solution, you would first need to add a tag to your button in the cellForRowAtIndexPath method.

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

    let cell = tableView.dequeueReusableCell(withIdentifier: yourReuseIdentifier, for: indexPath) as! YourCustomCell

    // Set your button tag to be equal to the indexPath.row:

    cell.button.tag = indexPath.row

    // Add a target to your button making sure that you return the sender like so:

    cell.button.addTarget(self, action: #selector(handleButtonTapped(sender:)), for: .touchUpInside)
}

And now this is how it would look like inside your handlerButtonTapped() method :

func handleButtonTapped(sender: UIButton) {

    // Now you can easily access the sender's tag, (which is equal to the indexPath.row of the tapped button).

    // Access the selected cell's index path using the sender's tag like so :

    let selectedIndex = IndexPath(row: sender.tag, section: 0)

    // And finally do whatever you need using this index :

    tableView.selectRow(at: selectedIndex, animated: true, scrollPosition: .none)

   // Now if you need to access the selected cell instead of just the index path, you could easily do so by using the table view's cellForRow method

    let selectedCell = tableView.cellForRow(at: selectedIndex) as! YourCustomCell

}

Another possibility, would be using closures.

Create a subclass of UITableViewCell :

class CustomTableCell: UITableViewCell {

    var shouldSelectRow: ((CustomTableCell) -> Void)?

    // MARK: User Interaction

    @IBAction func handleDidTapButton(_ sender: UIButton) {

        // Call your closure whenever the user taps on the button:

        shouldSelectRow?(self)
    }
}

Now you could set up your cellForRowAtIndexPath method like this:

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

        // ...

        cell.shouldSelectRow = { (selectedCell) in

             // Since you now know which cell got selected by the user, you can access via its index path:

             let selectedIndex = self.tableView.indexPath(for: selectedCell)

             // Do whatever you need using the selected cell here

             self.tableView.selectRow(at: selectedIndex, animated: true, scrollPosition: .none)
        }

        // ...

}

Note: You could also use delegates.

And it would work as well :)

  • 1
    You should not use tags to track index paths of buttons in a table view. It will fail if the table view allows you to insert, remove, or move any rows. – rmaddy Sep 17 '17 at 16:28
  • Well, the OP didn't say if he would implement cell insertion/removal so I thought I would give him a few different solutions so that he can choose the one that fits the best to his needs :). –  Sep 17 '17 at 16:34
  • 1
    That's fine. I'm simply pointing out a potential issue for future readers looking for a solution. – rmaddy Sep 17 '17 at 16:36
  • Thank you! Well that's actually very pertinent because depending on the situation it may indeed be a deal-breaker. –  Sep 17 '17 at 16:39