iphone cocoa-touch nsview drawrect

iphone - draws Vs layoutsubviews-NSView-Cocoa Touch



cocoa-touch drawrect (2)

No puedo encontrar una respuesta decente para explicarme la diferencia entre estas 2 funciones. ¿Cuándo se llama a cada uno y cómo se diferencia uno y luego al otro?

por ejemplo, ¿no puedo diseñar mis vistas dentro de drawrect?

Gracias


Tal vez no tenga todas las respuestas, pero puedo decirles que: - se llama a layoutSubviews cuando se cambia el marco de vista - se llama a drawRect cuando se llama a setNeedDisplay

La mayoría de las veces no usarás layoutSubviews.

Puede haber otros casos, pero podría darle una primera respuesta ^^

Buena suerte


-layoutSubviews se llama desde -layoutIfNeeded si el -layoutIfNeeded "diseño necesario" se estableció (usando -setNeedsLayout , o automáticamente cuando los límites de vista cambian). Úselo para posicionar su vista [ EDITAR: utilícelo para posicionar subvistas ].

-drawRect: se llama desde -displayIfNeeded si el indicador "se necesita pantalla" se estableció (usando -setNeedsDisplay , o automáticamente si se establece view.contentMode = UIViewContentModeRedraw ).

UIKit / CoreAnimation invoca automáticamente tanto -layoutIfNeeded como -displayIfNeeded antes de que las cosas se dibujen en la pantalla; Rara vez necesitas llamarlos directamente.

Puede colocar sus subvistas en -drawRect: (¡incluso puede agregar subvistas!), Pero esto no es prudente:

  • De forma predeterminada, -setNeedsDisplay no se llama automáticamente en un cambio de límites.
  • Implementando -drawRect: reduce el rendimiento (UIKit / CoreAnimation tiene que crear un contexto de gráficos respaldado por mapas de bits para usted); Solo hazlo si necesitas realizar un dibujo personalizado.
  • Necesitas volver a dibujar la vista en -drawRect: El dibujo es caro. Mover vistas alrededor es barato.
  • UIKit / CoreAnimation probablemente hace un pase de diseño seguido de un pase de dibujo. CoreAnimation puede utilizar la información de diseño para decidir qué vistas deben dibujarse (por ejemplo, podría ignorar vistas ocultas por subvistas opacas, vistas fuera de pantalla o subvistas fuera de los límites de una vista clipsToBounds = SÍ; o solo podría dibujar un sub-rect de vista amplia). Si mueve vistas durante el paso de dibujo, CoreAnimation podría no dibujarlas correctamente.

EDIT: Y algunos detalles más cuando estoy despierto:

¿Cuál es la diferencia entre "mostrar" y "dibujar"? La visualización se realiza mediante -[CALayer display] ; la implementación predeterminada es (aproximadamente)

  • Si el delegado de la capa responde a -displayLayer: llame a [self.delegate displayLayer:self] . -displayLayer: se supone que establece layer.content en (por ejemplo) un CGImage,
  • De lo contrario, si el delegado de la capa responde a -drawLayer:inContext: configure un contexto respaldado por mapa de bits, llame a [self.delegate drawLayer:self inContext:context] , y guarde la salida en layer.content (la salida es en realidad un CABackingStore , que es presumiblemente una API privada)
  • De lo contrario, no cambie layer.content .

La vista es el delegado de la capa, por lo que puede implementar -[MyView displayLayer:] lugar, y hacer cosas interesantes como

  • self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage) (que es aproximadamente lo que hace UIImageView)
  • Un no-op, para evitar cualquier "dibujo". Esto podría ser útil si ha subclasificado, por ejemplo, UIToolbar y desea darle un fondo transparente. (Esto también evita la creación de CGContext / CABackingStore).
  • Mueva las subvistas sin la penalización de rendimiento (pero todavía no es una buena idea por las razones anteriores).