¿Por qué esta transformación mediante CATransform3D networkinguce el ancho de la vista?

Echa un vistazo a la siguiente progresión de imágenes:

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Lo que está sucediendo aquí es primero que seleccioné "Béisbol", haciendo que las 3 vistas grises que ves giren a la izquierda para que la que tiene varios niveles esté en el medio (segunda image). Puede ver que ya en este punto el ancho de la vista se ha networkingucido sustancialmente. La tercera image se produce después de hacer clic en la vista que contiene los nombres de los deportes, haciendo que gire hacia el centro.

Por lo que puedo decir, el ancho de una vista se networkinguce cuando gira en el medio. Pero no tengo idea de por qué.

Aquí está el código relevante. pos refiere a dónde se ubicará la view en cuestión. 0 indica que está en el medio, 1 indica que está a la derecha del medio, -1 es uno a la izquierda del medio, etc.

 - (void)perspectiveView:(MenuSection *)view forPosition:(NSInteger)pos { CALayer *layer = view.layer; CATransform3D transform = CATransform3DIdentity; MenuSection *prevView = (pos >= 0) ? (MenuSection *)[self viewWithTag:view.tag - 1] : (MenuSection *)[self viewWithTag:view.tag + 1]; if (pos == 0) { view.changingToFrame = CGRectMake(round((480 - view.frame.size.width)/2), view.frame.origin.y, view.frame.size.width, view.frame.size.height); view.frame = view.changingToFrame; } else { if (pos == 1) { NSLog(@"%@",NSStringFromCGRect(prevView.changingToFrame)); view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform.m34 = 1.0 / 1000; } else if (pos == -1){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform.m34 = 1.0 / -1000; } else if (pos == 2){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform.m34 = 1.0 / 500; } else if (pos == -2){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform.m34 = 1.0 / -500; } view.frame = view.changingToFrame; transform = CATransform3DRotate(transform, 45.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f); } layer.transform = transform; } 

Lo he resuelto. Resulta que aplicar CATransform3D realmente cambia el marco de la vista. En el código que publiqué, cuando configuro el nuevo marco de la vista (porque gira en una position diferente), simplemente uso view.frame.size.width en CGRectMake() en un bash de mantener el ancho. PERO, ya que CATransform3D había modificado previamente el ancho, no obtengo el ancho real que deseo.

La solución fue subclasificar las UIViews necesarias y almacenar su marco original en un ivar. De esa manera, siempre puedo usar eso como punto de reference cuando muevo las vistas a diferentes posiciones.

No debería necesitar editar las matrices CATransform3D directamente (m34, etc …) para que este efecto funcione. Prueba esto:

 if (pos == 0) { view.changingToFrame = CGRectMake(round((480 - view.frame.size.width)/2), view.frame.origin.y, view.frame.size.width, view.frame.size.height); view.frame = view.changingToFrame; } else { if (pos == 1) { view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform = CATransform3DRotate(transform, M_PI/4.0f, 0.0f, 1.0f, 0.0f); } else if (pos == -1){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform = CATransform3DRotate(transform, -M_PI/4.0f, 0.0f, 1.0f, 0.0f); } else if (pos == 2){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform = CATransform3DRotate(transform, M_PI/3.0f, 0.0f, 1.0f, 0.0f); } else if (pos == -2){ view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height); transform = CATransform3DRotate(transform, -M_PI/3.0f, 0.0f, 1.0f, 0.0f); } view.frame = view.changingToFrame; } layer.transform = transform; 

y luego juega con esos angularjs hasta que se vea bien.