den330 den330 - 5 months ago 15
Swift Question

How to make tableViewCell handle both tap and longPress?

I put this in cellForRowAtIndexPath

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(CalorieCountViewController.handleLongPress))
cell.addGestureRecognizer(longPress)
longPress.cancelsTouchesInView = true
let tapPress = UITapGestureRecognizer(target: self, action: #selector(CalorieCountViewController.handleTapPress))
cell.addGestureRecognizer(tapPress)
tapPress.cancelsTouchesInView = true


and put these(code below) outside of it, and removed didSelectRowAtIndexPath function entirely, use indexPathForSelectedRow instead to get which row user just selected.

func handleLongPress(sender: UILongPressGestureRecognizer){
let index = tableView.indexPathForSelectedRow!
doSomething(index)
}

func handleTapPress(sender: UITapGestureRecognizer){
let index = tableView.indexPathForSelectedRow!
doSomethingElse(index)
}


Turns out indexPathForSelectedRow returns nil, but I did select a row, and there is no "deselectRowAtIndexPath" anywhere in my code.

Answer

Don't add the UILongPressGestureRecognizer to Cell. Add it to UITableView in viewDidLoad

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(CalorieCountViewController.handleLongPress))
yourTableView.addGestureRecognizer(longPress)

Get the touched cell index by

func handleLongPress(sender: UILongPressGestureRecognizer){
    if longPressGestureRecognizer.state == UIGestureRecognizerState.Began {
         let touchPoint = longPressGestureRecognizer.locationInView(self.view)
         if let indexPath = yourTableView.indexPathForRowAtPoint(touchPoint) {
        // your code here, get the row for the indexPath or do whatever you want
         }
    }
}

Instead of UITapGestureRecognizer use didSelectRowAtIndexPath is a better way