2012-01-17 14 views
5

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

enter image description here enter image description here enter image description here¿Por qué esta transformación usando CATransform3D reduce el ancho de la vista?

lo que está sucediendo aquí es la primera que he seleccionado "béisbol", haciendo que los 3 puntos de vista grises que se ven a rotar a la izquierda de manera que el que tiene los distintos niveles están en el medio (segunda imagen). Puedes ver que ya en este punto el ancho de la vista se ha reducido sustancialmente. La tercera imagen se produce después de hacer clic en la vista que contiene los nombres de deportes, lo que hace que gire de nuevo al centro.

De lo que puedo decir, la anchura de miras se reduce cuando se gira hacia el centro. Pero no tengo idea de por qué.

Aquí está el código relevante. pos se refiere a dónde se va a ubicar el view en cuestión. 0 indica que está en el medio, 1 indica que es una a la derecha de la media, -1 es uno a la izquierda del centro, 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; 
} 
+0

Resolví esto agregando una cantidad muy pequeña de transformación del eje z. No siempre funciona, y si se hace incorrectamente, doblará su vista a lo largo del eje y = x. – CodaFi

+0

¿Para qué sirve transform.m34? He girado vistas como esta sin que el ancho cambie nunca. No estoy seguro de lo que está pasando ... – bentford

+0

Obtuve el código de transformación de esta publicación: http://stackoverflow.com/questions/347721/how-do-i-apply-a-perspective-transform-to-a-uiview. ¿Puedes proporcionar un ejemplo de código sobre cómo has girado las vistas? Si elimino las instrucciones transform.m34, entonces acabo terminando con transformaciones que se ven así: http://cl.ly/2Z0v0P1U1T2a1p240x3L – maxedison

Respuesta

7

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

la solución era subclase el necesario UIViews y almacenar su trama original en una Ivar. De esa forma, siempre puedo usar eso como punto de referencia cuando muevo las vistas a diferentes posiciones.

+2

+1 por tomarse el esfuerzo de escribir la solución –

+0

+1 para explicar por qué votó. – Martin

0

No debería ser necesario para editar las matrices CATransform3D directamente (m34, etc.) para que este efecto funcione. Pruebe 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 juegue con esos ángulos hasta que se vea bien.

+0

Tienes que modificar 'm34' directamente si quieres perspectiva. Consulte "Modificación de la estructura de datos de transformación" en * [Core Animation Programming Guide] (http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html#//apple_ref/ doc/uid/TP40006082-SW14) *. –

Cuestiones relacionadas