Search code examples
macoscocoagesture-recognitionnsbuttonlong-press

NSPressGestureRecognizer called before minimumPressDuration


I need my NSButton to respond to regular clicks, as well as long presses. I am adding NSPressGestureRecognizer like so:

override func viewDidLoad() {
    super.viewDidLoad()

    let gr = NSPressGestureRecognizer()
    gr.minimumPressDuration = 1
    gr.action = #selector(handleLongPress)
    button.addGestureRecognizer(gr)  
}

func handleLongPress(gr: NSPressGestureRecognizer) {

    if gr.state == .Began {
        Swift.print("long press")
    }

}

Unfortunately, the handleLongPress randomly fires even at short single clicks, or double clicks. It happens even if i set the minimumPressDuration to higher values.

I have tried playing with the shouldBeRequiredToFailByGestureRecognizer but it is not solving the problem.

Is there something i am missing with my code?


Solution

  • I have solved this by handling multiple gesture recognizers:

    the class must implement NSGestureRecognizerDelegate

    var singleClick:NSClickGestureRecognizer?
    var longClick:NSPressGestureRecognizer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        longClick = NSPressGestureRecognizer()
        longClick!.minimumPressDuration = 1
        longClick!.action = #selector(handleGestureLong)
        longClick!.delegate = self
    
        singleClick = NSClickGestureRecognizer()
        singleClick?.numberOfClicksRequired = 1
        singleClick!.action = #selector(handleGestureSingle)
        singleClick!.delegate = self
    
        btn.addGestureRecognizer(longClick!)
        btn.addGestureRecognizer(singleClick!)
    
    }
    
    func gestureRecognizer(gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOfGestureRecognizer otherGestureRecognizer: NSGestureRecognizer) -> Bool {
        if gestureRecognizer == singleClick && otherGestureRecognizer == longClick {
            return false
        }
        return true
    }
    
    func handleGestureSingle(gr: NSClickGestureRecognizer) {
    
        switch gr.state {
    
        case .Ended:
            print("single click")
            break
        default:
            break
    
        }
    }
    
    func handleGestureLong(gr: NSPressGestureRecognizer) {
    
        switch gr.state {
    
        case .Began:
            print("long click")
            break
        default:
            break
    
        }
    }