2012-03-21 9 views
7

Estoy subclasando CALayer para proporcionar mi propio método de dibujo. Para la optimización llamo al -[MyLayer setNeedsDisplayInRect:] en lugar de -[MyLayer setNeedsDisplay]. En el método de dibujo obtengo el rect que se debe volver a dibujar a través del CGContextGetClipBoundingBox().- [CALayer setNeedsDisplayInRect:] hace que toda la capa se vuelva a dibujar

Si utilizo esta capa como base capa de un UIView todo funciona como se esperaba. El problema surge, tan pronto como utilizo mi capa personalizada como una subcapa de otro CALayer. Than CGContextGetClipBoundingBox() siempre devuelve el rect de los límites de esa capa.

¿Alguna idea?

[EDIT]

Parece que no hay ninguna garantía de que el contenido de la CALayer se almacena en caché y sólo la parte sucia se vuelve a dibujar. Hice una pequeña prueba y almacené el rect que necesita mostrar como una propiedad separada. El resultado fue que solo esta parte era visible en la pantalla.

Ahora voy a renderizar en un contexto de imagen y mantener esa imagen como un caché. En el método de dibujar, solo mostraré la imagen en caché.

+0

¿Las capas que no se ven tienen su propiedad 'masksToBounds' establecida en' YES'? Si no, hay una buena razón por la cual no se cortarán. – MrMage

+0

Desafortunadamente esto no lo resuelve. El problema es que 'CGContextGetClipBoundingBox()' devuelve los límites de la capa y no de la región que debe actualizarse según lo documentado por Apple: * Las subclases que desean encontrar la región real para dibujar pueden llamar a CGContextGetClipBoundingBox. * [DrawInCOntext:] (https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instm/CALayer/drawInContext :) –

+0

¿Alguna vez ha llegado al abajo de esto? Tengo el mismo problema molesto. – mprivat

Respuesta

6

Desafortunadamente, la documentación de Apple está en conflicto ya que los documentos en -setNeedsDisplayInRect no indican si el método funciona en la práctica. Basado en mi propia experiencia, this technote conjuntos y como es:

Tenga en cuenta que, debido a la forma en que el iPhone/iPod touch/iPad actualiza su pantalla, toda la vista se vuelve a dibujar si se llama -setNeedsDisplayInRect: o -setNeedsDisplay :.

Dicho esto, hay varias cosas que puede considerar si cree que está golpeando una pared debido a un dibujo redundante.

  • Si dibuja imágenes, la mejora de rendimiento más grande que puede hacer es utilizar imágenes de las mismas dimensiones en las que dibuja. Si no lo están, intente almacenar en caché su imagen dejándola en un contexto de mapa de bits fuera de la pantalla y tráigala más tarde.
  • Echa un vistazo a la propiedad shouldRasterize en CALayer. Esto puede ser una bendición si está tratando de manipular una capa cuyas subcapas potencialmente constituyen una jerarquía de capas complejas. Asegúrate de ver cómo te va en los instrumentos marcando la casilla Color Hits Green and Misses Red en el instrumento Core Animation. Si ve mucho rojo, lo más probable es que usar shouldRasterize duela más de lo que ayuda.
  • Incluso mejor que shouldRasterize es aplanar la jerarquía de su capa, ya que entonces puede evitar la sobrecarga adicional en la que incurre shouldRasterize al acoplar la jerarquía de capas en tiempo real. Por supuesto, esto no siempre es posible, pero no tengas miedo de probar :)
  • Si estás dibujando imágenes, intenta experimentar con tu blending mode. Si está dibujando imágenes opacas, no es necesario utilizar métodos de fuente normal sobre (que usan ancho de banda de lectura/escritura). Pruebe kCGBlendModeCopy, que le permite eliminar la sobrecarga del ancho de banda de lectura.
  • Eche un vistazo a CGLayerRef, que le permite almacenar en caché la salida de Core Graphics en varias llamadas a sus métodos de dibujo. Mi experiencia es que, a menos que estés haciendo un gran empujón de píxeles, esto termina siendo más costoso que solo redibujar. Ver this para una lectura interesante.
  • Sobre todo, Instruments es tu amigo.Vea un par de videos de WWDC anteriores (2012, 2011, and 2010); todos ellos tienen una gran información sobre cómo ajustar el rendimiento.

Por favor, siéntase libre de hacer cualquier otra pregunta si algo que he dicho tiene poco sentido.

+0

¿Hay alguna forma de obligar a los CALayers más bajos a que cuelguen su redibujado/rasterización hasta después de que otros UIViews los oculten en lugar de anularlos? – Confused

Cuestiones relacionadas