Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 596
den330 Avatar asked Jun 12 '16 02:06

den330


2 Answers

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

like image 127
Bala Avatar answered Nov 15 '22 20:11

Bala


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
        }
    }
}
like image 42
Abbas Habibnejad Avatar answered Nov 15 '22 22:11

Abbas Habibnejad