6

I have a UITableView with multiple sections and in my cellForRowAtIndexPath method I add a UITapGestureRecognizer to the cell's imageView (each cell has a small image). I have been successful in accessing that image (in order to change it) by using:

var imageView : UIImageView! = sender.view! as UIImageView

What I need to do now, however, is access the cell's data, which I believe means I need to be able to access the cell in order to get the section and row number. Can anyone advise on how to do this? The idea is that I am changing the image to an unchecked checkbox if the task is done, but then in my data I need to actually mark that task as done.

iOSBeginner
  • 363
  • 4
  • 17

4 Answers4

21

In your function that handles the tap gesture recognizer, use tableView's indexPathForRowAtPoint function to obtain and optional index path of your touch event like so:

func handleTap(sender: UITapGestureRecognizer) {
    let touch = sender.locationInView(tableView)
    if let indexPath = tableView.indexPathForRowAtPoint(touch) {
        // Access the image or the cell at this index path
    }
}

From here, you can call cellForRowAtIndexPath to get the cell or any of its content, as you now have the index path of the tapped cell.

Ian
  • 12,538
  • 5
  • 43
  • 62
  • Hi, this almost worked! However, the location must be incorrect as it is performing operations on the wrong cells. Any thoughts on this? – iOSBeginner Apr 01 '15 at 01:05
6

You can get the position of the image tapped in order to find the indexPath and from there find the cell that has that image:

var position: CGPoint =  sender.locationInView(self.tableView)
var indexPath: NSIndexPath = self.tableView.indexPathForRowAtPoint(position)!    
var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
  • Hi, this almost worked! However, the location must be incorrect as it is performing operations on the wrong cells. Any thoughts on this? – iOSBeginner Apr 01 '15 at 01:05
  • 1
    Should be: var cell = self.tableView.cellForRowAtIndexPath(indexPath) – Josh Nov 11 '15 at 19:18
2

You're missing that you can use the Delegate design pattern here.

Create a protocol that tells delegates the state changes in your checkbox (imageView):

enum CheckboxState: Int {
    case .Checked = 1
    case .Unchecked = 0
}

protocol MyTableViewCellDelegate {
    func tableViewCell(tableViewCell: MyTableViewCell, didChangeCheckboxToState state: CheckboxState)
}

And assuming you have a UITableViewCell subclass:

class MyTableViewCell: UITableViewCell {

    var delegate: MyTableViewCellDelegate?

    func viewDidLoad() {

        // Other setup here...

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "didTapImage:")
        imageView.addGestureRecognizer(tapGestureRecognizer)
        imageView.userInteractionEnabled = true
    }

    func didTapImage(sender: AnyObject) {

        // Set checked/unchecked state here
        var newState: CheckboxState = .Checked // depends on whether the image shows checked or unchecked

        // You pass in self as the tableViewCell so we can access it in the delegate method
        delegate?.tableViewCell(self, didChangeCheckboxToState: newState)
    }

}

And in your UITableViewController subclass:

class MyTableViewController: UITableViewController, MyTableViewCellDelegate {

    // Other methods here (viewDidLoad, viewDidAppear, etc)...

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) {
        var cell = tableView.dequeueReusableCellWithIdentifier("YourIdentifier", forIndexPath: indexPath) as MyTableViewCell

        // Other cell setup here...

        // Assign this view controller as our MyTableViewCellDelegate
        cell.delegate = self

        return cell
    }

    override func tableViewCell(tableViewCell: MyTableViewCell, didChangeCheckboxToState state: CheckboxState) {

        // You can now access your table view cell here as tableViewCell

    }

}

Hope this helps!

0

Get tableView's cell location on a specific cell. call a function which holds the gesture of cell's Objects Like UIImage or etc.

let location = gesture.location(in: tableView)
   let indexPath = tableView.indexPathForRow(at: location)
   Print(indexPath.row)
   Print(indexPath.section)
Parth
  • 634
  • 8
  • 15