17

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.

den330
  • 387
  • 1
  • 3
  • 15
  • only add long press gesture on UITableViewCell and for tap you can use "didSelectRowAtIndexPath" delegate method of UITableView – Sandeep Kumar Jun 12 '16 at 03:03

3 Answers3

42

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

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

Get the touched cell index by

@objc private func handleLongPress(sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        let touchPoint = sender.location(in: tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            // your code here, get the row for the indexPath or do whatever you want
        }
    }
}

Instead of UITapGestureRecognizer use didSelectRowAtIndexPath is a better way

IBAction
  • 2,131
  • 2
  • 9
  • 14
Bala
  • 1,224
  • 1
  • 13
  • 25
6

Update Swift4:

Add these lines in viewDidLoad of your viewController class (in this example class's name is YourViewController)

override func viewDidLoad() {
    super.viewDidLoad()

    let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPress(longPressGestureRecognizer:)))
    self.view.addGestureRecognizer(longPressRecognizer)
}

Now add this func in your viewController class

@objc func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {

    if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
        let touchPoint = longPressGestureRecognizer.location(in: self.view)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            // add your code here
            // you can use 'indexPath' to find out which row is selected
        }
    }
}
Ever Uribe
  • 639
  • 6
  • 13
Abbas Habibnejad
  • 433
  • 5
  • 14
  • 1
    This actually will show the wrong indexPath. You need to add the gestureRecognizer to the tableView in `viewDidLoad`, not the view. Replace `self.view.addGestureRecognizer(longPressRecognizer)` with `tableView.addGestureRecognizer(longPressRecognizer)`. Also, change `let touchPoint = longPressGestureRecognizer.location(in: self.view)` to be `let touchPoint = longPressGestureRecognizer.location(in: tableView)`. – Phontaine Judd Aug 22 '19 at 01:00
5

Based on Bala Answer here is on swift 4 or 5

override func viewDidLoad() {
        super.viewDidLoad()
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longpress))
        tableView.addGestureRecognizer(longPress)
    }

Here is the method

@objc func longPress(sender: UILongPressGestureRecognizer) {

            if sender.state == UIGestureRecognizer.State.began {
                let touchPoint = sender.location(in: tableView)
                if let indexPath = tableView.indexPathForRow(at: touchPoint) {
                    // your code here, get the row for the indexPath or do whatever you want
                    print("Long press Pressed:)")
                }
            }


        }
finalpets
  • 281
  • 4
  • 6
  • Suggestion to change the `action` parameter to `#selector(longPress)`. Currently it is all lowercase and as such is an unresolved symbol. – John Harrington Jun 20 '22 at 22:24