Pregunta

Tengo un irritante menor en un NSCollectionView en el que el NSCollectionViewItem romper visualmente cuando me desplazo la ventana.

La tasa de ruptura depende de la velocidad de desplazamiento. Por ejemplo, si se desplazan lentamente la ruptura se produce con más frecuencia. Desplazamiento rápido por lo menos. Parece que el problema es cuando la costumbre NSView del NSCollectionViewItem estoy usando cruces de la frontera del marco visible.

Mi NSView (vista personalizada de la NSCollectionViewItem) tiene una muy simple algoritmo de dibujo -. Nada demasiado complejo

En esencia, se crea un marco dentro del dirtyRect del método drawRect y crear una serie de imágenes en el interior 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];
}

He tratado de bloquear el enfoque y la liberación de antes y después del código, así como establecer el contexto gráfico y su restauración -. Ninguno de los cuales parece resolver el problema

Estoy usando Snow Leopard -. No es que crea que hace una diferencia

Solución de actualización

Para cualquier persona interesada aquí es la solución al problema según lo recomendado por NSResponder. Estaba creando la mOuterFrame inicial basado en el drawRect: métodos dirtyRect que, como se señaló, era la cosa incorrecta a hacer. Un cambio rápido de:

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

Para un punto de origen 0 en base:

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

También pellizcado la eficiencia del código, siendo lo que estoy usando sólo rectángulos, como se sugiere aunque el cambio de código anterior fue suficiente para resolver el problema en sí mismo. He tenido que añadir un cambio de obtener una línea de dos píxeles. Nuevo método:

-(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];
}
¿Fue útil?

Solución

La primera cosa que noté es que el código anterior es más bien un desperdicio, ya que va a crear un montón de caminos cuando simplemente podría estar utilizando NSFrameRect () y NSRectFill () en su lugar.

En segundo lugar, la geometría de lo que dibuje no debe ser dependiente del rectángulo que se pasa a -drawRect :. Rectángulo que sólo le dice lo que la zona es para actualizar, por lo que puede ser más eficiente para decidir qué debe dibujar si su visión es compleja.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top