Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable didSelectRowAtIndexPath on Long press gesture on Tableview Cell

I have been trying to setup a long press gesture recognizer on UITableView. The gesture is working fine, but i want to disable the didSelectRowAtIndexPath delegate function of UITableView when Long Press gesture is recognised.

In short, if user single tap on the cell i have to push a new UIViewController, and if user long press on the cell i have to show an UIActionSheet.

extension GroupChatListingViewController : UIGestureRecognizerDelegate {

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func setupLongPress() {

    longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress))
    longPressGesture.minimumPressDuration = 1.0 // 1 second press
    longPressGesture.delegate = self
    longPressGesture.cancelsTouchesInView = false
    self.tableView.addGestureRecognizer(longPressGesture)
}

func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {

    if longPressGestureRecognizer.state == UIGestureRecognizerState.began {

        self.tableView.allowsSelection = false
        let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            self.showActionSheet()
        }
    }
    else if longPressGestureRecognizer.state == .ended {
        self.tableView.allowsSelection = true
    }
} }
like image 289
Mr. Bean Avatar asked Feb 14 '18 12:02

Mr. Bean


People also ask

Why can’t I use viewwithtag with cellforrowatindexpath?

This problem is very common, and the “accepted answer” in StackOverflow is one that set the tag of the button during cellForRowAtIndexPath:. This “misuse” of a view tag means you may not use viewWithTag:, and secondly it could have bug when you delete/move cells (because cellForRowAtIndexPath: will not be called).

How to get the index path of a UITableView cell?

The trick is to get the superview of the button, which will be the cell, and then using tableView.indexPathForCell (cell) to get the index path. @IBAction func tapOnButton(sender: UIButton) { let cell = sender.superview as! UITableViewCell let indexPath = tableView.indexPathForCell(cell) }

How to add a uigesturerecognizer to a uitableviewcell?

But the best answer is to create your custom UITableViewCell, then have your UIButton delegate the call to your view controller. This requires more code, and a custom class, but is the most correct. If you are tapping on any other UIView, you could handle similarly. But in this case, you cannot add the UIGestureRecognizer to the view on storyboard.


1 Answers

@optimus comment helped me to solve this problem, this is a very genuine situation of disabling didSelectRowAtIndexPath when long press gesture is recognised on the tableview cell which has not been answered on the Internet

override func viewDidLoad() {

    super.viewDidLoad()
    setupLongPress()
    setupTapPress()
}

extension GroupChatListingViewController : UIGestureRecognizerDelegate {

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func setupLongPress() {

    longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress))
    longPressGesture.minimumPressDuration = 1.0 // 1 second press
    longPressGesture.delegate = self
    longPressGesture.cancelsTouchesInView = false
    self.tableView.addGestureRecognizer(longPressGesture)
}

func setupTapPress() {

    singlePressGesture = UITapGestureRecognizer(target: self, action: #selector(tapPress))
    singlePressGesture.delegate = self
    singlePressGesture.cancelsTouchesInView = false
    self.tableView.addGestureRecognizer(singlePressGesture)
}

func tapPress(gesture: UIGestureRecognizer) {

    if gesture.state == .ended {
        let touchPoint = gesture.location(in: self.tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            // do your task on single tap
        }
    }
}

func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {

    if longPressGestureRecognizer.state == UIGestureRecognizerState.began {

        let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            self.showActionSheet()
        }
    }
} }
like image 197
Mr. Bean Avatar answered Sep 30 '22 16:09

Mr. Bean