2010-07-23 8 views
12

Tengo un paginador UIScrollView en el que el usuario páginas horizontalmente a través de imágenes, como Apple's Photos.app. Eso funciona, pero ahora estoy tratando de agregar soporte de rotación.Limpiar transiciones de autorrotación en una paginación UIScrollView

Tengo la vista girando OK y he logrado establecer los cuadros contentSize, bounds y subviews 'correctamente para adaptarlos a las diferentes orientaciones. Entonces, antes y después de la rotación, todo está bien.

Sin embargo, las transiciones mismas son incómodas. La primera imagen gira perfectamente, como si el eje de rotación estuviera en el centro muerto de la imagen (marco de desplazamiento de vista). La segunda imagen "oscila" porque el eje de rotación está en el mismo lugar: el centro de la primera imagen. Mientras más lejos esté de la primera imagen, más rápido será el "columpio".

Probablemente pueda enmascarar esto al superponer una UIView opaca antes de la rotación y ocultarla después. Pero eso es un truco. Debe haber una manera elegante de hacer esto ...

Respuesta

38

Francamente, no sé lo que estás haciendo, ya que no nos has mostrado nada en absoluto.

¡Pero!

Creé un proyecto de muestra con algunas vistas en una vista de desplazamiento, y funciona bien. Siéntase libre de desarmarlo como lo desee. Funciona al crear 5 vistas y agregarlas a la vista de desplazamiento. Luego, después de configurar estas vistas por primera vez, y cada vez que la aplicación gira, llama a mi método alignSubviews para colocarlas en las ubicaciones de la página derecha y hacerlas del mismo tamaño que la vista de desplazamiento, mientras actualiza la vista de desplazamiento contentSize . Antes de que se produzca la rotación, realiza un seguimiento de la página en la que se encuentra actualmente la vista de desplazamiento y luego la restablece en esa página durante la rotación (porque el tamaño de la página debe cambiar).

Download "Rotolling"!

screenshot http://cl.ly/43de79be29c5a03a1775/content

+0

excelente ejemplo! No publiqué ningún código porque sabía que tendría que descartar lo que tenía. La moraleja de la historia es que si me encuentro configurando y restableciendo manualmente marcos de vista por todo el lugar, lo estoy haciendo mal. – alexantd

+0

Genial. Solo funciona fuera de la caja. Gracias. – Gerd

+4

Gracias por un buen ejemplo. Necesito hacer una corrección para el lanzamiento exitoso en iOS 6: [window setRootViewController: viewController]; a la aplicación: método didFinishLaunchingWithOptions. – kaspartus

1

Parece que está aplicando la magia, necesaria para obtener la versión girada en la pantalla en el lugar correcto, de la manera incorrecta.

Dado que no compartió ningún código, lo siguiente es solo conjeturas. Presumiblemente, aplica una rotación y una traducción. Es suena como si estuviera girando el contenido del UIScrollView. Hacer esto bien será difícil. Es difícil decir algo concluyente sin código, pero si solo tienes 1 rotación y 1 traducción, lo estás haciendo de la manera incorrecta. Necesita traducir la vista actual al punto de pivote, rotar y traducir de nuevo. De lo contrario, la traducción será parte de la rotación (de ahí el gran swing).

Será mejor que gire el UIScrollView. Siempre estará en una ubicación definida (a saber: la pantalla) con un centro definido. El contenido luego rotará con él.

7

observo esta información adicional para más adelante hacer referencia a mí mismo. Lo resolví con la idea de la solución de @jtvandes. Sin embargo, en mi caso, fue suficiente con estas implementaciones. Forzar el diseño de nuevo rompió mi punto de vista.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    currentPageOffset = [hostingScrollView contentOffset].x/[hostingScrollView bounds].size.width; 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    // Layout changed instantly at this time. 
    // So we have to force to set offset instantly by setting animation to NO. 
    [hostingScrollView setContentOffset:CGPointMake([hostingScrollView bounds].size.width * currentPageOffset, 0.0f) animated:NO]; 
} 
1

Una solución simple que funciona bien es registrarse para recibir notificaciones cuando se cambia el contentSize del UIScrollView y luego actualizar el contentOffset en ese momento.

En el método de carga Ver Añadir esta línea:

[self addObserver:theScrollView forKeyPath:@"contentSize" options:0 context:nil]; 

En el método de descarga de vista añadir esta línea:

[self removeObserver:self forKeyPath:@"contentSize"]; 

captura la notificación:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    theScrollView.contentOffset = page * theScrollView.bounds.width; 
} 
Cuestiones relacionadas