Question

J'ai un irritant mineur dans un NSCollectionView où la rupture de NSCollectionViewItem visuellement lorsque je fais défiler la fenêtre.

Le taux de rupture dépend du taux de défilement. Par exemple, si je fais défiler lentement la rupture se produit plus souvent. défilement rapide moins. Il semble que le problème est quand la coutume NSView du NSCollectionViewItem J'utilise traverse la limite du cadre visible.

Mon NSView (vue personnalisée du NSCollectionViewItem) a un algorithme de dessin très simple -. Rien de trop complexe

Pour l'essentiel, je crée un cadre dans le dirtyRect de la méthode drawRect et créer quelques images à l'intérieur que:

-(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];
}

Je l'ai essayé le verrouillage de la mise au point et la libération avant et après le code, ainsi que la définition du contexte graphique et restaurer -. Dont aucun ne semble résoudre le problème

J'utilise Snow Leopard -. Pas que je crois que cela fait une différence

Solution Mise à jour

Pour toute personne intéressée ici est la solution au problème tel que recommandé par NSResponder. Je créais la mOuterFrame initiale basée sur les méthodes de drawRect: dirtyRect qui, comme l'a souligné, était la chose à faire incorrecte. Un changement rapide de:

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

Pour un point d'origine à base 0:

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

J'ai aussi peaufiné l'efficacité du code, être comme je suis en utilisant uniquement des rectangles, comme le suggère bien que le changement de code ci-dessus était suffisant pour résoudre le problème en soi. Je devais ajouter un changement pour obtenir une ligne de deux pixels. Nouvelle méthode:

-(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];
}
Était-ce utile?

La solution

La première chose que j'ai remarqué est que votre code ci-dessus est plutôt inutile, puisque vous créez un tas de chemins quand vous pourriez utiliser NSFrameRect () et NSRectFill () au lieu.

En second lieu, la géométrie de ce que vous dessinez ne devrait pas dépendre du rectangle passé à -drawRect :. Ce rectangle vous dit exactement ce que la zone de mise à jour est, de sorte que vous pouvez être plus efficace pour décider quoi dessiner si votre vue est complexe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top