在Cocoa OSX中双击

时间:2010-02-02 00:15:35

标签: cocoa macos double-click nsresponder

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

7 个答案:

答案 0 :(得分:28)

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

答案 1 :(得分:7)

普通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")
}

答案 2 :(得分:6)

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

示例实施:

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

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

答案 3 :(得分:5)

一般情况下,应用程序会查看clickCount == 2 on - [mouseUp:]以确定双击。

一个改进是跟踪鼠标点击位置 - [mouseDown:],并看到鼠标向上位置的增量很小(x和y都是5点或更小)。 / p>

答案 4 :(得分: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
 }

答案 5 :(得分:0)

就个人而言,我检查双击鼠标功能:

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

    if ([theEvent clickCount] == 2)
    {

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

     }

}

答案 6 :(得分:0)

我更喜欢onStopJobonCreate方法的替代方法是onDestroy

mouseDown: