NSCollectionView nuevo trazado de desplazamiento provoca la desintegración de Gráficos
-
20-09-2019 - |
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];
}
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.