Search code examples
iosswiftuitableviewuitouch3dtouch

3D Touch force gesture activates cell tap on touch end


I have subclassed a UITableView in my app so that I can intercept touch events. I am using this to allow me to provide 3D Touch gestures on the entire view (including on top of the table view).

This works great, however the problem is that using 3D Touch on one of the cells and then releasing your finger activates the cell tap.

I need to only activate the cell tap if there is no force exerted. I should explain that I am fading an image in gradually over the entire screen as you apply pressure.

Here is my subclass:

protocol PassTouchesTableViewDelegate {
    func touchMoved(touches: Set<UITouch>)
    func touchEnded(touches: Set<UITouch>)
}

class PassTouchesTableView: UITableView {
    var delegatePass: PassTouchesTableViewDelegate?

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesMoved(touches, withEvent: event)

        self.delegatePass?.touchMoved(touches)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesEnded(touches, withEvent: event)

        self.delegatePass?.touchEnded(touches)
    }
}

And here are the methods I'm calling from my view controller when the touches end and move:

internal func touchMoved(touches: Set<UITouch>) {
    let touch = touches.first

    self.pressureImageView.alpha = (touch!.force / 2) - 1.0
}

internal func touchEnded(touches: Set<UITouch>) {
    UIView.animateWithDuration(0.2, animations: {
        self.pressureImageView.alpha = 0.0
    })
}

Solution

  • You could create a boolean named isForceTouch which is set to false in touchesBegan, and then once force touch is detected, set it to true. Then in didSelectRowAtIndexPath just return false if isForceTouch is true. It may need tweaking but that should work.