21

I have a custom UITableViewCell subclass and its associated xib. I have a UILabel and a UIButton in this cell and I have wired the touch up inside action of the button to the subclass.

What I need is when that button in the cell is tapped, to get the indexpath of the cell which has that button. And maybe send it back to the view controller via a delegate or something.

Since I'm inside a UITableViewCell subclass, I can't use a solution like this because I don't have a reference to the tableview from inside the cell subclass. Upon further investigation I found another solution and I implemented it in Swift like this.

import UIKit

class ContactCell: UITableViewCell {

    @IBOutlet weak var nameLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        selectionStyle = .None
    }

    @IBAction func callButtonPressed(sender: UIButton) {
        let indexPath = (self.superview as UITableView).indexPathForCell(self)
        println("indexPath?.row")
    }

}

But when I tap on the button, it crashes with an error message saying Swift dynamic cast failed.

Any idea what's wrong with my code?

Or I'm open to any other suggestions which would allow me to achieve the desired result in any other way.

Thank you.

Community
  • 1
  • 1
Isuru
  • 30,617
  • 60
  • 187
  • 303
  • Sounds like you need a delegate: http://stackoverflow.com/questions/24099230/delegates-in-swift – ullstrm Sep 16 '14 at 11:28
  • What is the reason for you to know the related indexPath? `println("indexPath?.row")` is obviously not a real reason. What is the model behind all that? – Imanou Petit Sep 16 '14 at 13:00
  • @POB The reason is I have taken out the tableview's Data source methods and put them in a separate reusable class as described in [this](http://www.objc.io/issue-1/lighter-view-controllers.html) article. My custom cell has a button and now I need to get the indexpath of the cell which the button is tapped. – Isuru Sep 16 '14 at 17:06
  • 1
    @Isuru: I answered a quite similar question a few weeks ago [here](http://stackoverflow.com/a/25613657/1966109) but I don't think anymore that it's a good app design. I think what you want is an index in your datasource (array) and not a cell index path (same result but much better app design with the first one). We should build our models on our datasources and not rely in a lazy way on cells index paths. – Imanou Petit Sep 16 '14 at 19:05
  • @POB You're right. I kinda realized it too because what I actually wanted to do was something with a property of the object that is in that cell, not the indexpath directly. I'm gonna change the delegate to return the index. Thanks :) – Isuru Sep 16 '14 at 19:45

3 Answers3

23

Sounds like you need a delegate:

Delegates in swift?

Then just pass the cell itself as a parameter to the delegate, and then you can easily do tableView.indexPathForCell(cellFromDelegateMethod)

Community
  • 1
  • 1
ullstrm
  • 9,812
  • 7
  • 52
  • 83
2

Hey you can use "Tag" of the button also.Inside the cellForRowAt method of table delegate u can tag the button with Indexpath.row . here is the example what i m tried to say.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// get ur cell nib .As it has a button
cell.startOrConntinuBtn.addTarget(self, action: #selector(sumbitOrContinue), for: .touchUpInside) 

cell.startOrConntinuBtn.tag = indexPath.row }

and in the touch method "sumbitOrContinue" -

 func sumbitOrContinue(sender: UIButton!) { 
let tag = sender.tag
// do what you want to do like this example

let detail = self.detailList[tag]
let vc  = self.storyboard?.instantiateViewController(withIdentifier: "mockExamInt") as! MockWindowVc
vc.detailId = detail.id
self.navigationController?.pushViewController(vc, animated: true)}
Sibasish
  • 346
  • 3
  • 10
1

UIButton.Type really does not have member superview, but sender have

var cell: UITableViewCell = sender.superview.superview as UITableViewCell

  • This is a great way to do it if using a collection view embeded in a tableview and you want to enable interactions for buttons within the collection view cell but still allow for the embed collectionview cell to segue to the correct tableview items – Tom Jul 31 '17 at 13:39