Subprocesss de la capa de transformación y layoutSubviews

mi pregunta está relacionada con

UIView / CALayer: transforma los desencadenantes layoutSubviews en superview

Dónde se informa que, a partir de una respuesta de ETI de Apple:

En general, al cambiar una propiedad geométrica de una vista (o capa), se disparará una cascada de invalidaciones de layout en la jerarquía de vistas, ya que las vistas padre pueden tener restricciones de Diseño automático que involucran al hijo modificado. Tenga en count que el layout automático está activo de alguna forma, independientemente de si lo ha habilitado explícitamente.

En mi caso, tengo una jerarquía de vista muy simple donde la vista A contiene la vista B

En el layoutSubviews de A estoy configurando el marco de B.

Cuando realizo animaciones (transformar y opacidad) en la capa de respaldo de B, a veces se llama a layoutSubviews de A. Esto es obviamente un problema porque estoy configurando el marco de B en las vistas de layout de A y esto rompe la animation.

¿Cómo puedo evitar este conflicto entre el layout de B y la animation?

Descubrí que es posible resolver este problema de muchas maneras:

1) Guarde temporalmente la transformación, cambie el marco y vuelva a aplicar la transformación:

[super layoutSubviews]; //backup the transform value before the layout CATransform3D transform = self.internalView.layer.transform; //Set identity and update all the necessary frames self.internalView.layer.transform = CATransform3DIdentity; self.internalView.frame = self.bounds; //set back the transform self.internalView.layer.transform = transform; 

2) Cambia los límites y el centro de la vista sin tocar el marco. Los límites y el centro no afectan la transformación. Tiene sentido porque el cuadro se calcula internamente leyendo los límites de la capa, la position, la transformación, el punto de anclaje.

 self.internalView.bounds = self.bounds; self.internalView.center = CGPointMake(floorf(CGRectGetWidth(self.bounds)/2.0f), floorf(CGRectGetHeight(self.bounds)/2.0f)); 

3) Apple en un TSI (reportado aquí UIView / CALayer: Transform triggers layoutSubviews en superview ) sugiere a

"Envuelva los contenidos de su celda en una vista intermedia. Cuando modifique la transformación de esta vista intermedia, solo se debe invalidar el layout de la celda, por lo que no se llamará su costoso método de layout.

Si eso no funciona, cree un mecanismo para señalar su costoso método de layout cuando realmente tiene que hacer (o no) hacer el trabajo. Esta podría ser una propiedad que configuró cuando los únicos cambios que realiza son las transformaciones ".

4) También experimenté apagar completamente la reproducción automática para las subminas de mi vista personalizada. Puede leer este muy buen artículo de obj.io donde se explica que si elimina la llamada a [super layoutSubviews] desde la implementación layoutSubviews , está optando por la opción autolayout para su vista personalizada y todas sus sub-vistas.

La pisada es que debe tener en count que en el caso de que agregue como subvista una vista con restricciones, el sistema de autoajuste boostá una exception como esta:

*** Finalización de la aplicación debido a la exception no detectada 'NSInternalInconsistencyException', razón: 'El layout automático aún se requiere después de ejecutar -layoutSubviews. La implementación de MyView de -layoutSubviews necesita llamar super. '

Las soluciones 1 y 2 son buenas si tiene una lógica de layout simple. Si su lógica de layout es expansiva, puede implementar 3 o 4 y árbitro a esta otra pregunta UIView / CALayer: Transformar triggers layoutSubviews en supervisión