18

NSResponder 似乎没有鼠标双击事件。有没有一种简单的方法来捕捉双击?

4

7 回答 7

34

mouseDown:和方法将mouseUp:NSEvent 对象作为参数,其中包含有关点击的信息,包括clickCount.

于 2010-02-02T00:34:04.760 回答
8

通常应用程序会查看 -[mouseUp:] 上的 clickCount == 2 来确定双击。

一种改进是跟踪鼠标单击 -[mouseDown:] 的位置,并查看鼠标向上位置的增量很小(x 和 y 上的 5 点或更少)。

于 2013-03-21T15:05:38.030 回答
8

普通clickCount解决方案的问题在于,双击被简单地视为两次单击。我的意思是你仍然可以单击。如果您想对单次点击做出不同的反应,您需要在单纯的点击计数之上做一些事情。这是我最终得到的结果(在 Swift 中):

private var _doubleClickTimer: NSTimer?

// a way to ignore first click when listening for double click
override func mouseDown(theEvent: NSEvent) {
    if theEvent.clickCount > 1 {
        _doubleClickTimer!.invalidate()
        onDoubleClick(theEvent)
    } else if theEvent.clickCount == 1 { // can be 0 - if delay was big between down and up
        _doubleClickTimer = NSTimer.scheduledTimerWithTimeInterval(
            0.3, // NSEvent.doubleClickInterval() - too long
            target: self,
            selector: "onDoubleClickTimeout:",
            userInfo: theEvent,
            repeats: false
        )
    }
}


func onDoubleClickTimeout(timer: NSTimer) {
    onClick(timer.userInfo as! NSEvent)
}


func onClick(theEvent: NSEvent) {
    println("single")
}


func onDoubleClick(theEvent: NSEvent) {
    println("double")
}
于 2015-08-21T13:32:52.703 回答
7

NSEvent为 s 生成的smouseDown:mouseUp:一个名为 的属性clickCount。检查是否为两个以确定是否发生了双击。

示例实现:

- (void)mouseDown:(NSEvent *)event {
    if (event.clickCount == 2) {
        NSLog(@"Double click!");
    }
}

只需将其放在您的NSResponder(例如NSView)子类中。

于 2013-10-20T18:13:45.990 回答
2

mouseDown:我更喜欢的+NSTimer方法的替代方法是NSClickGestureRecognizer.

    let doubleClickGestureRecognizer = NSClickGestureRecognizer(target: self, action: #selector(self.myCustomMethod))
    doubleClickGestureRecognizer.numberOfClicksRequired = 2

    self.myView.addGestureRecognizer(doubleClickGestureRecognizer)
于 2018-10-01T08:43:34.623 回答
1

我实现了类似于@jayarjo 的东西,只是它更加模块化,因为您可以将它用于任何 NSView 或其子类。这是一个自定义手势识别器,它将识别单击和双击动作,但在超过双击阈值之前不能识别单击:

//
//  DoubleClickGestureRecognizer.swift
//

import Foundation
/// gesture recognizer to detect two clicks and one click without having a massive delay or having to implement all this annoying `requireFailureOf` boilerplate code
final class DoubleClickGestureRecognizer: NSClickGestureRecognizer {

    private let _action: Selector
    private let _doubleAction: Selector
    private var _clickCount: Int = 0

    override var action: Selector? {
        get {
            return nil /// prevent base class from performing any actions
        } set {
            if newValue != nil { // if they are trying to assign an actual action
                fatalError("Only use init(target:action:doubleAction) for assigning actions")
            }
        }
    }

    required init(target: AnyObject, action: Selector, doubleAction: Selector) {
        _action = action
        _doubleAction = doubleAction
        super.init(target: target, action: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(target:action:doubleAction) is only support atm")
    }

    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        _clickCount += 1
        let delayThreshold = 0.15 // fine tune this as needed
        perform(#selector(_resetAndPerformActionIfNecessary), with: nil, afterDelay: delayThreshold)        
        if _clickCount == 2 {
            _ = target?.perform(_doubleAction)
        }
    }

    @objc private func _resetAndPerformActionIfNecessary() {
        if _clickCount == 1 {
            _ = target?.perform(_action)
        }
        _clickCount = 0
    }
}

用法 :

let gesture = DoubleClickGestureRecognizer(target: self, action: #selector(mySingleAction), doubleAction: #selector(myDoubleAction))
button.addGestureRecognizer(gesture)

@objc func mySingleAction() {
 //  ... single click handling code here
}

@objc func myDoubleAction() {
 // ... double click handling code here
 }
于 2018-04-15T15:55:37.293 回答
0

就个人而言,我检查了双击 mouseUp 函数:

- (void)mouseUp:(NSEvent *)theEvent
{

    if ([theEvent clickCount] == 2)
    {

        CGPoint point = [theEvent locationInWindow];
        NSLog(@"Double click on: %f, %f", point.x, point.y);

     }

}
于 2015-11-10T15:18:22.760 回答