Frage

Ich habe eine benutzerdefinierte NSView (es ist eine von vielen, und sie alle leben in einem NSCollectionView - Ich glaube nicht, das ist relevant, aber wer weiß). Wenn ich die Ansicht klicken, ich will es seine Auswahl Zustand ändern (und neu zu zeichnen sich entsprechend); wenn ich die Ansicht doppelklicken, mag ich es ein größeres Vorschaufenster für das Objekt Pop-up, das gerade wurde doppelgeklickt.

Meine erste sah wie folgt aus:

- (void)mouseUp: (NSEvent *)theEvent {
    if ([theEvent clickCount] == 1) [model setIsSelected: ![model isSelected]];
    else if ([theEvent clickCount] == 2) if ([model hasBeenDownloaded]) [mainWindowController showPreviewWindowForPicture:model];
}

, die feine meist gearbeitet. Außer, wenn ich der Ansicht, doppelklicken Sie auf die Auswahlzustandsänderungen und das Fenster erscheint. Dies ist nicht genau das, was ich will.

Es scheint, wie ich zwei Möglichkeiten. Ich kann entweder den Auswahlzustand zurückzukehren, wenn sie einen Doppelklick (Lösen den verirrten Einzelklick) reagiert, oder ich kann eine Art von NSTimer Lösung finagle vor der Reaktion auf den einzigen Klick in einer Verzögerung zu bauen. Mit anderen Worten, kann ich sicherstellen, dass ein zweiter Klick, bevor die Änderung der Auswahlzustand nicht ausbleibt.

Das schien elegantes, so war es der Ansatz, den ich anfangs nahm. Die einzige wirkliche Führung ich von Google fand, war auf einem ungenannten Ort mit einem Bindestrich im Namen. Dieser Ansatz meist arbeitet mit einem großen Nachteile.

Die noch offene Frage ist: „Wie lange soll mein NSTimer warten?“. Die ungenannte Website schlägt vor, die Carbon-Funktion GetDblTime() verwenden. Abgesehen von in 64-Bit-Anwendungen unbrauchbar ist, die einzige Dokumentation ich es finden kann, sagt, dass es Uhr-Tick ist zurück. Und ich weiß nicht, wie diese in Sekunden für NSTimer zu konvertieren.

Also, was ist die „richtige“ Antwort hier? Herumfummeln mit GetDblTime()? „Rückgängig“, um die Auswahl auf einem Doppelklick? Ich kann nicht den Cocoa-idiomatischen Ansatz ausrechnen.

War es hilfreich?

Lösung

die Änderung des Auswahlzustandes Aufschieben ist die empfohlene (von dem, was ich gesehen habe) Art und Weise, dies zu tun.

Es ist ziemlich einfach zu implementieren:

- (void)mouseUp:(NSEvent *)theEvent
{
    if([theEvent clickCount] == 1) {
        [model performSelector:@selector(toggleSelectedState) afterDelay:[NSEvent doubleClickInterval]];
    }
    else if([theEvent clickCount] == 2)
    {
        if([model hasBeenDownloaded])
        {
                [NSRunLoop cancelPreviousPerformRequestsWithTarget: model]; 
                [mainWindowController showPreviewWindowForPicture:model];
        }
    }
}

(Beachten Sie, dass in 10,6, das Doppelklick-Intervall als Klassenmethode auf NSEvent zugänglich ist)

Andere Tipps

Wenn Ihr Ein-Klick und Doppelklick-Operationen wirklich getrennt und unabhängig sind, benötigen Sie einen Timer auf dem ersten Klick zu bedienen und warten, ob ein Doppelklick passieren wird. Das gilt auf jeder Plattform.

Aber das bringt eine unangenehme Verzögerung in Ihrer Ein-Klick-Operation, die normalerweise nicht mögen Benutzer. So sehen Sie nicht, diesen Ansatz verwendet sehr oft.

Ein besserer Ansatz ist, um Ihre Ein-Klick und Doppelklick-Operationen zusammenhängen und sich ergänzen. Zum Beispiel, wenn Sie ein Symbol im Finder mit einem Klick es aktiviert ist (sofort), und wenn Sie ein Symbol doppelklicken wird ausgewählt und geöffnet (sofort). Das ist das Verhalten, das Sie sollten darauf abzielen.

Mit anderen Worten, die Folgen eines Ein-Klick sollten Sie mit Ihrem Doppelklick auf Befehl bezogen werden. Auf diese Weise können Sie mit den Auswirkungen der Ein-Klick in Ihrem Doppel-Click-Handler behandeln, ohne auf die Verwendung eines Timer zurückgreifen zu müssen.

Fügen Sie zwei Objekte zu Ihrer benutzerdefinierten Ansicht.

// CustomView.h
@interface CustomView : NSView {
  @protected
    id      m_target;
    SEL     m_doubleAction;
}
@property (readwrite) id target;
@property (readwrite) SEL doubleAction;

@end

Überschreiben Sie die mouseUp: Methode in Ihrer benutzerdefinierten Ansicht.

// CustomView.m
#pragma mark - MouseEvents

- (void)mouseUp:(NSEvent*)event {
    if (event.clickCount == 2) {
        if (m_target && m_doubleAction && [m_target respondsToSelector:m_doubleAction]) {
            [m_target performSelector:m_doubleAction];
        }
    }
}

Registrieren Sie Ihren Controller als target mit einer doubleAction.

// CustomController.m
- (id)init {
    self = [super init];
    if (self) {
        // Register self for double click events.
        [(CustomView*)m_myView setTarget:self];
        [(CustomView*)m_myView setDoubleAction:@selector(doubleClicked:)];
    }
    return self;
}

implementieren, was getan werden soll, wenn ein Doppelklick passiert.

// CustomController.m
- (void)doubleClicked:(id)sender {
  // DO SOMETHING.
}

Ich persönlich denke man sich fragen müssen, warum Sie diese Nicht-Standard-Verhalten wollen.

Können Sie in einer anderen Anwendung verweisen, die den ersten Klick in einem Doppelklick behandelt, als ich von einem einzigen Mausklick zu sein? Ich kann mich an jeden ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top