Frage

Ich habe einen kleinen Reizstoff in einem NSCollectionView in welcher NSCollectionViewItem'S brechen visuell auf, wenn ich das Fenster scrolle.

Die Trennungsrate hängt von der Scrollenrate ab. Wenn ich beispielsweise langsam scrolle, tritt die Trennung öfter auf. Schnell scrollen Sie weniger. Es scheint, dass das Problem darin besteht, wenn die benutzerdefinierte NSView der NSCollectionViewItem Ich verwende die Grenze des sichtbaren Rahmens.

Meine nsview (benutzerdefinierte Ansicht der NSCollectionViewItem) hat einen sehr einfachen Zeichnungsalgorithmus - nichts zu komplexes.

Im Wesentlichen erstelle ich einen Rahmen im DirtyRect der DrawRect -Methode und erstelle ein paar Frames darin:

-(void)drawRect:(NSRect)dirtyRect
{   
    NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
    NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
    NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
    NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);

    NSBezierPath * mOuterFramePath = [NSBezierPath bezierPathWithRect:mOuterFrame];
    NSBezierPath * mSelectedFramePath = [NSBezierPath bezierPathWithRect:mSelectedFrame];
    NSBezierPath * mRedFramePath = [NSBezierPath bezierPathWithRect:mRedFrame];
    NSBezierPath * mInnerFramePath = [NSBezierPath bezierPathWithRect:mInnerFrame];

    [mainBackgroundColor set];
    [mOuterFramePath fill];

    if (selected)
        [[NSColor yellowColor] set];
    else
        [mainBackgroundColor set];

    [mSelectedFramePath fill];

    if (isRedBorder)
        [[NSColor redColor] set];
    else
        [mainBackgroundColor set];

    [mRedFramePath fill];

    [[NSColor blackColor] set];
    [mInnerFramePath fill];
}

Ich habe versucht, den Fokus zu sperren und vor und nach dem Code zu veröffentlichen sowie den Grafikkontext festzulegen und wiederherzustellen - keine davon scheinen das Problem zu lösen.

Ich benutze Schneeleopard - nicht, dass ich denke, das macht einen Unterschied.

Lösungs -Update

Für jeden, der hier interessiert ist, ist die Lösung für das von NSResponder empfohlene Problem. Ich habe die Initiale erstellt mOuterFrame basierend auf dem drawRect: Methoden dirtyRect Was, wie ausgedrückt, die falsche Sache war. Eine kurze Änderung von:

NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);

Zu einem 0 -basierten Originierungspunkt:

NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);

Ich habe auch die Effizienz des Codes optimiert, da ich nur Rechtecke verwende, wie vorgeschlagen, obwohl die obige Codeänderung ausreicht, um das Problem an sich selbst zu beheben. Ich musste eine Änderung hinzufügen, um eine Zwei -Pixel -Linie zu erhalten. Neue Methode:

-(void)drawRect:(NSRect)dirtyRect
{   
    NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
    NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
    NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
    NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);

    [NSBezierPath setDefaultLineWidth:2.0];

    [mainBackgroundColor set];
    [NSBezierPath strokeRect:mOuterFrame];

    if (selected)
        [[NSColor yellowColor] set];
    else
        [mainBackgroundColor set];

    [NSBezierPath strokeRect:mSelectedFrame];

    if (isRedBorder)
        [[NSColor redColor] set];
    else
        [mainBackgroundColor set];

    [NSBezierPath strokeRect:mRedFrame];

    [[NSColor blackColor] set];
    [NSBezierPath strokeRect:mInnerFrame];
}
War es hilfreich?

Lösung

Als erstes wurde mir aufgefallen, dass Ihr obiger Code ziemlich verschwenderisch ist, da Sie stattdessen eine Reihe von Pfaden erstellen, wenn Sie nur nsframerect () und nsRectFill () verwenden können.

Zweitens sollte die Geometrie dessen, was Sie zeichnen, nicht vom Rechteck abhängen, der an -Drawrect übergeben wird:. Dieses Rechteck sagt Ihnen nur mit, wie der Bereich aktualisiert werden soll, sodass Sie effizienter entscheiden können, was Sie zeichnen sollen, wenn Ihre Ansicht komplex ist.

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