-1

My goal is to perform segue when i tap on imageview of that cell. but the error does not appear when i use addTarget on a button.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        cell.imageView.userInteractionEnabled = true
        let tapImageView = UITapGestureRecognizer(target: self, action: #selector(HomeFeedViewController.tapImageView(_:)))
        cell.imageView.addGestureRecognizer(tapImageView)
        return cell as CastleCell
    }

func tapImageView(sender: AnyObject) {
        let center = sender.center
        let point = sender.superview!!.convertPoint(center, toView:self.tableView) //line of error
        let indexPath = self.tableView.indexPathForRowAtPoint(point)
        let cell = self.tableView.cellForRowAtIndexPath(indexPath!) as! CastleCell

        performSegueWithIdentifier("SegueName", sender: self)
    }

The line of error is let point =...

The error i get is:

fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

but the error does not appear when i use addTarget on a button. what could be wrong? thanks.

johnniexo88
  • 313
  • 5
  • 17
  • Why are there two `!`s on `superview`? – keithbhunter Aug 15 '16 at 18:47
  • @keithbhunter had it on a button and that was the only way it worked without error – johnniexo88 Aug 15 '16 at 19:01
  • Well I don't know what was going on with the button, but having back to back force unwraps is almost certainly a bad idea. In this case, your `superview` is probably not nil here and this code would work if you unwrap it once. But then you unwrap it a second time; this is probably why it crashes. – keithbhunter Aug 15 '16 at 19:03
  • I suggest that you use a protocol and delegate callback. This enables you to keep the gesture recogniser in the cell class where it belongs and doesn't require storing an index path in the cell (which will break if cells are inserted/deleted). See here for the basic approach http://stackoverflow.com/questions/28659845/swift-how-to-get-the-indexpath-row-when-a-button-in-a-cell-is-tapped/38941510#38941510 – Paulw11 Aug 15 '16 at 20:28

1 Answers1

4

Am not really fond of playing with points and Superview. What is can suggest is to make a class for UITapGestureRecognizer as follows which can hold extra data. In your case it would be an index path

class CustomGesture: UITapGestureRecognizer {
    let indexPath:NSIndexPath? = nil
}

And then in your didSelect you can add the index path to the newly created CustomGesture class which be would be like:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        cell.imageView.userInteractionEnabled = true
        let tapImageView = CustomGesture(target: self, action: #selector(HomeFeedViewController.tapImageView(_:)))
        tapImageView.indexPath = indexPath// Add the index path to the gesture itself
        cell.imageView.addGestureRecognizer(tapImageView)
        return cell as CastleCell
    }

Now since you have added the indexPath you don't need to play around with super view's and you can access the cell like this:

func tapImageView(gesture: CustomGesture) {

        let indexPath = gesture.indexPath!
        let cell = self.tableView.cellForRowAtIndexPath(indexPath!) as! CastleCell

        performSegueWithIdentifier("SegueName", sender: self)
    }
Harsh
  • 2,852
  • 1
  • 13
  • 27