NSResponder wydaje się nie mieć zdarzenia dwukrotnego kliknięcia myszką. Czy istnieje łatwy sposób na podwójne kliknięcie?Catching podwójne kliknięcie w Cocoa OSX
Odpowiedz
Metoda przyjmuje obiekt NSEvent jako argument z informacją o kliknięciach, w tym clickCount
.
Zwykle aplikacje sprawdzają clickCount == 2 na - [mouseUp:], aby określić dwukrotne kliknięcie.
Jednym z udoskonaleń jest śledzenie położenia kliknięcia myszą na - [mouseDown:] i zobaczenie, że delta w miejscu, w którym znajduje się mysz, jest niewielka (5 punktów lub mniej w x i y).
Wygenerowane dla i mouseUp:
s mają właściwość o nazwie clickCount
. Sprawdź, czy są dwa, aby określić, czy nastąpiło podwójne kliknięcie.
Przykładowa realizacja:
- (void)mouseDown:(NSEvent *)event {
if (event.clickCount == 2) {
NSLog(@"Double click!");
}
}
Wystarczy umieścić, że w NSResponder
(taki jak NSView
) podklasy.
Co zwykle robisz, jeśli potrzebujesz obsługiwać oba - jedno kliknięcie i dwukrotne kliknięcie. Oczywiście będziesz musiał zignorować jedno kliknięcie, jakby w końcu okazało się, że jest to dwukrotne kliknięcie? – jayarjo
@jayarjo - Nie mogę myśleć o miejscu, w którym czynność wykonywana jednym kliknięciem nie byłaby wykonywana, gdyby okazało się, że konieczne jest podwójne kliknięcie. W polach tekstowych pojedyncze kliknięcie umieszcza kursor w określonym miejscu. Podwójne kliknięcie podkreśla całe słowo. Przesunięcie kursora na jedno kliknięcie było nieszkodliwe. W grach RTS (przynajmniej Blizzard) pojedyncze kliknięcie wybiera pojedynczą jednostkę, a podwójne kliknięcie wybiera wszystkie jednostki tego typu. Jeśli chcesz, aby podwójne kliknięcie zrobiło coś zupełnie innego niż pojedyncze kliknięcie, możesz przemyśleć cały swój UX. – ArtOfWarfare
Problem z prostym rozwiązaniem clickCount
polega na tym, że podwójne kliknięcie jest traktowane po prostu jako dwa pojedyncze kliknięcia. Mam na myśli, że wciąż masz jedno kliknięcie. A jeśli chcesz inaczej reagować na to pojedyncze kliknięcie, potrzebujesz czegoś oprócz zwykłego liczenia kliknięć. Oto co mam zakończyła się (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")
}
Osobiście sprawdzić podwójne kliknięcie na mouseUp funkcji:
- (void)mouseUp:(NSEvent *)theEvent
{
if ([theEvent clickCount] == 2)
{
CGPoint point = [theEvent locationInWindow];
NSLog(@"Double click on: %f, %f", point.x, point.y);
}
}
IMHO jest to najbardziej użytecznej odpowiedzi, jak również odpowiedzi niejawny pytanie, czy zareagować na drugi mouseDown lub drugi mouseUp. Oczywiście w pewnych sytuacjach może być sens odejście od normy. Niestety, sami Apple nie są całkowicie zgodni z jednym standardem (Finder i poczta w górę, Kalendarz w dół) ... – fzwo