2009-07-25 22 views
43

¿Cuándo y cómo se usa layoutIfNeeded? Sé que cuando cambiamos el diseño de una vista, podemos llamar al setNeedsLayout para actualizar el diseño, pero no estamos seguros de cuándo se debe usar layoutIfNeeded.¿Cómo se usa layout IfNeeded?

NOTA: Tengo layoutIfNeeded usado en el código actual, pero se me olvidó en qué contexto se utilizó.

Respuesta

57

layoutIfNeeded obliga al receptor a diseñar sus subvistas inmediatamente si es necesario.

Supongamos que ha anulado layoutSubviews y UIKit siente que su punto de vista requiere la disposición por cualquier razón (por ejemplo, que llamó setNeedsLayout al manejar alguna acción del usuario). Luego, se llamará inmediatamente a su método personalizado layoutSubviews en lugar de cuando normalmente se llamaría en la secuencia de eventos de bucle de ejecución de UIKit normal (después del manejo de eventos, pero antes de drawRect:).

Un ejemplo de por qué es posible que tenga que llamar layoutIfNeeded dentro de un solo bucle de ejecución:

  1. cambiar el tamaño de una vista personalizada que contiene una vista de tabla con un diseño personalizado. setNeedsLayout se establece para llamar a layoutSubviews más tarde.
  2. Un objeto de controlador le pide a la vista de tabla que se desplace a alguna celda en particular al manejar un evento de usuario.
  3. Su vista personalizada realiza algunos tamaños personalizados de la vista de tabla en layoutSubviews que cambia el tamaño de la vista de tabla.

El problema es cuando el controlador solicitó que la vista de tabla se desplazara (paso 2), la vista de tabla tenía límites obsoletos. Los límites actualizados solo se establecerán en la vista de tabla más tarde (paso 3). Lo que el controlador quería que fuera la vista de tabla para desplazarse puede que no esté realmente visible después de que se haya hecho layoutSubviews. Entonces, una solución sería que el controlador llamara al layoutIfNeeded en situaciones donde sabe que esto podría ocurrir.

-9

setNeedsLayout realmente llama a layout IfNeeded, por lo que si su llamada estableceNeedsDisplay no hay ninguna razón para invocar layoutIfNeeded. De esta forma, setNeedsLayout es un método conveniente para llamar a layoutIfNeeded que hace el trabajo pesado.

+14

Esto no es verdad. setNeedsLayout marcará la vista del diseño, lo que dará lugar a que se invoque a layoutSubviews en otro ciclo de ciclo de ejecución. Llamar a layout IfNeeded dará lugar a que se invoque a layoutSubviews en el mismo ciclo de ciclo de ejecución. Para probar esto, establezca un punto de interrupción en layoutSubviews y luego un punto de interrupción en una llamada a setNeedsLayout. Si avanzas una línea, notarás que no rompes en layoutSubviews. Sin embargo, si rompe en layout IfNeeded y avanza una línea, notará que se romperá en layoutSubviews antes de avanzar. – tyler

+1

dang, qué gran downvote –