Frage

Warum wird „mouseExited/mouseEntered“ nicht aufgerufen, wenn die Maus NStrackingArea durch Scrollen oder Animieren verlässt?

Ich erstelle Code wie diesen:

Maus eingegeben und verlassen:

-(void)mouseEntered:(NSEvent *)theEvent {
    NSLog(@"Mouse entered");
}

-(void)mouseExited:(NSEvent *)theEvent
{
    NSLog(@"Mouse exited");
}

Tracking-Bereich:

-(void)updateTrackingAreas
{ 
    if(trackingArea != nil) {
        [self removeTrackingArea:trackingArea];
        [trackingArea release];
    }

    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
    trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
                                             options:opts
                                               owner:self
                                            userInfo:nil];
    [self addTrackingArea:trackingArea];
}

Mehr Details:

Ich habe NSViews als Unteransichten in der Ansicht von NSScrollView hinzugefügt.Jeder NSView hat seinen eigenen Tracking-Bereich und wenn ich meinen ScrollView scrolle und den Tracking-Bereich verlasse, wird „mouseExited“ nicht aufgerufen, aber ohne Scrollen funktioniert alles einwandfrei.Das Problem ist, dass beim Scrollen „updateTrackingAreas“ aufgerufen wird und ich denke, dass dies Probleme verursacht.

* Das gleiche Problem besteht nur bei NSView, ohne es als Unteransicht hinzuzufügen, das ist also kein Problem.

War es hilfreich?

Lösung

Wie Sie im Titel der Frage angemeldet haben, werden von Mautmaßnahmen und maus mit der Maus nur dann aufgerufen, wenn sich die Maus bewegt. Um zu sehen, warum dies der Fall ist, schauen wir uns zunächst den Prozess des Hinzufügens von NStrackingArtAns zum ersten Mal an.

Als einfaches Beispiel erstellen wir eine Ansicht, die normalerweise einen weißen Hintergrund zeichnet, aber wenn der Benutzer über die Ansicht schwebt, zieht es einen roten Hintergrund. Dieses Beispiel verwendet Arc. generasacodicetagpre.

Es gibt zwei Probleme mit diesem Code. Erstens, wenn -AwakeFromNib aufgerufen wird, wenn die Maus bereits in der Ansicht ist, wird -MouseNiederlassung nicht aufgerufen. Dies bedeutet, dass der Hintergrund noch weiß ist, obwohl die Maus über der Ansicht ist. Dies wird tatsächlich in der NSView-Dokumentation für den Assuminside-Parameter von -addtrackingRect erwähnt: Eigentümer: userdata: uSnumeInside:

Wenn ja, wird das erste Ereignis generiert, wenn der Cursor kequect verlässt, unabhängig davon, ob der Cursor in der Nähe ist, wenn das Tracking-Rechteck hinzugefügt wird. Wenn nein das erste Ereignis erzeugt wird, wenn der Cursor beitritt, wenn der Cursor anfänglich innen ist, oder wenn der Cursor eingeht, wenn der Cursor anfänglich außerhalb von außen ist.

Wenn in beiden Fällen die Maus im Trackingbereich befindet, werden keine Ereignisse erzeugt, bis die Maus den Trackingbereich verlässt.

Um dies zu beheben, wenn wir den Tracking-Bereich hinzufügen, müssen wir herausfinden, ob der Cursor sich im Trackingbereich befindet. Unsere -CreateTrackingArea-Methode wird somit generasacodicetagpre.

Das zweite Problem ist das Scrollen. Beim Scrollen oder Bewegen einer Ansicht müssen wir die NStrackingArt in dieser Ansicht neu berechnen. Dies geschieht durch Entfernen der Tracking-Bereiche und fügen sie anschließend wieder hinzu. Wie bereits erwähnt, wird - updatetRackingArtAreas aufgerufen, wenn Sie die Ansicht scrollen. Dies ist der Ort, um den Bereich zu entfernen und erneut hinzuzufügen. generasacodicetagpre.

und das sollte sich um Ihr Problem kümmern. Zugegebenermaßen müssen Sie den Mausportort finden und dann umschalten, um Jedes Mal, wenn Sie einen Tracking-Bereich hinzufügen, einwandfreie Konvertieren, so dass Sie schnell alt werden, so dass ich empfehlen würde, eine Kategorie auf NSView zu erstellen, die dies automatisch behandelt. Sie können nicht immer in der Lage sein, [Self MouseNered: NIL] oder [Self Mousexited: Nil], also möchten Sie vielleicht die Kategorie dazu bringen, ein paar Blocks anzunehmen. Einer zum Ausführen, wenn sich die Maus im NSTRACKINGArEA befindet, und einer zu laufen, wenn dies nicht der Fall ist.

Andere Tipps

@Michael bietet eine tolle Antwort und hat mein Problem gelöst.Aber es gibt eine Sache,

if (CGRectContainsPoint([self bounds], mouseLocation))
{
    [self mouseEntered: nil];
}
else
{
    [self mouseExited: nil];
}

ich fand CGRectContainsPoint Funktioniert in meiner Box nicht CGPointInRect,

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