2010-09-05 16 views
7

tengo una vista de capas de alojamiento establecido así en una subclase personalizada NSView:setNeedsDisplay Calling: SÍ a la capa de alojamiento de vista no se vuelve a dibujar la vista

[self setLayer:rootLayer]; 
[self setWantsLayer:YES]; 

agrego todas las subcapas al árbol de capas después de llamar al setNeedsDisplay en cada subcapa. El contenido de cada capa es proporcionado por un método drawLayer:inContext del delegado de mi capa.

Aquí está mi problema:

Después de inicializar mi opinión, la vista se dibuja correctamente. Sin embargo, cuando el modelo ha cambiado y llamo al [myCustomView setNeedsDisplay:YES]; desde mi controlador de vista, no se llama al drawLayer:inContext.

Estoy confundido ahora cómo actualizar la vista:

  • ¿Tengo que llamar al método setNeedsDisplay en cada CALayer en el árbol de capas?
  • ¿No debería la llamada de setNeedsDisplay:YES en la vista de alojamiento de capa desencadenar el redibujado de todo el árbol de capa?

Gracias por su ayuda.

Editar

he encontrado algo en la Clase NSView referencia

Una vista capa respaldados es una vista que está respaldada por una capa de núcleo de animación. Cualquier dibujo realizado por la vista se almacena en caché en la capa de respaldo. Configuró una vista respaldada por capa simplemente invocando setWantsLayer: con un valor de SÍ. La clase de vista creará automáticamente una capa de respaldo para usted, y usted utilizará los mecanismos de dibujo de la clase de vista. Cuando utilice vistas respaldadas por capas, nunca debe interactuar directamente con la capa.

Una vista de alojamiento de capa es una vista que contiene una capa de animación principal que tiene la intención de manipular directamente. Usted crea una vista de alojamiento de capa instanciando una instancia de una clase de capa Core Animation y configurando esa capa utilizando el método setLayer: de la vista. Después de hacerlo, invocarás setWantsLayer: con un valor de SÍ. Al usar una vista de alojamiento de capa, no debe confiar en la vista para dibujar, ni debe agregar subvistas a la vista de alojamiento de capa.

link to documentation

En mi caso, tengo una vista de capas de alojamiento. Entonces, ¿eso significa que tengo que desencadenar el redibujado manualmente? ¿Debo implementar un método pseudo drawRect en el NSView personalizado para llamar al setNeedsDisplay apropiado en los CALayers que cambiaron?

Respuesta

9

Después de seguir investigando en el sample code de Apple de un menú tipo kiosco, descubrí que si está utilizando una vista de alojamiento de capa, tiene que encargarse de las actualizaciones de pantalla que son necesarias debido a los cambios del modelo. Llamar al setNeedsDisplay:YES en el NSView no hará nada.

Entonces, lo que uno tiene que hacer si uno tiene que actualizar una vista, uno debe escribir un método como reloadData y en él uno debe llamar al setNeedsDisplay en cada CALayer que necesita una actualización. Todavía no estoy seguro de si una llamada a este método en la capa raíz se propagará a través de todas las capas secundarias, pero no lo creo.

Resolví el problema ahora llamando al setNeedsDisplay en los CALayers individuales que necesitaban recablear. Funciona sin problemas

+0

Su enlace al código de ejemplo está roto, quizás este es el reemplazo: https://developer.apple.com/library/mac/samplecode/CoreAnimationKioskStyleMenu/Introduction/Intro.html#//apple_ref/doc/uid/ DTS40009512 –

2

También hay una práctica utilizada frecuentemente de tener un "drawRect" vacía, a la -(void) drawRect:(NSRect)dirtyRect {} para ayudar a coaccionar a las cosas en el dibujo, creo a través de buena ole view.needsDisplay = YES;.

y debe tenerse en cuenta .. que lo que está sucediendo es que de hecho - diciendo su NSView *view; es layer.delegate = view; hace que la capa que se desprende cuando se llama .... [layer setNeedsDisplay]; través - (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {...} ..

lo largo de la misma vena ... al decir layer.layoutManager = view ... demandas posteriores que [layer setNeedsLayout]; se cumplirán únicamente cuando se implementa el método - (void) layoutSublayersOfLayer:(CALayer *)layer {..} ..

Estos conceptos vitales son pasados ​​por alto/esparcidos en documentos de Apple ... y son realmente tan fundamental para hacer que absolutamente cualquier cosa funcione en absoluto.

+0

puede explicar un poco más de manera amigable para principiantes. – carbonr

+0

@carbonr Sé que es confuso. Pero lo que dije es tan simple como se pone. Si las cosas no se muestran correctamente, y su vista es el delegado de la capa ... Debe implementar 'drawLayer: inContext' y tal vez tener un' drawRect: 'vacío Y llamar a' setNeedsDisplay'. Léelo 10 veces si es necesario, pero la información está allí. Si recuerdo correctamente, eso es. ;) –

Cuestiones relacionadas