2010-11-08 22 views
18

Estoy usando UIScrollView y una imagen en él como paging una imagen por página. Tengo un problema al girar el iPhoneUIScrollView deshabilita el desplazamiento mientras gira en iPhone/iPad

Cuando giro el iPhone, me desplazo a scrollDownScroll (Método delegado de vista en desplazamiento). Debido a esto, mi paginación se altera y el número de página cambia.

¿Cuál es la solución?

+0

que tienen el mismo problema. .., ¿lograste resolver el problema? – negersiu

+1

@ Maciulis ... ¿Qué hice exactamente en ese momento ... pero verifico el código ... y no estoy usando el método scrollViewDidScroll y usando scrollViewDidEndDecelerating ... y uso una variable global para el número de página actual ... espero que esto Ayuda o dime exactamente lo que quieres –

Respuesta

13

Encontré un extraño comportamiento indocumentado al rotar un UIScrollView paginado.

Cuando la vista de desplazamiento se coloca en la última página y el usuario cambia la orientación, el sistema operativo desplaza el UIScrollView algunos píxeles hacia atrás para compensar la diferencia entre alto y ancho.

Básicamente recibí las siguientes llamadas para cualquier página.

willRotateToInterfaceOrientation:duration 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

Y para la última página:

willRotateToInterfaceOrientation:duration 
scrollViewDidScroll: 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

Que mal estado con mis páginas también. El problema es que en willRotate, los límites no han sido actualizados por el sistema operativo, sin embargo, y en willAnimate que tienen los nuevos límites y se puede calcular el nuevo tamaño, pero es demasiado tarde ...

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 

    CGSize tempSize = [self.pagingScrollView contentSize]; 
    NSUInteger padding = abs(pagingScrollView.frame.size.width - pagingScrollView.frame.size.height); 
    tempSize.width += padding; 
    [self.pagingScrollView setContentSize:tempSize]; 
    [...] 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration{ 
    CGSize newSize = ... // Compute new content size based on new orientation 
    [self.pagingScrollView setContentSize:newSize]; 
} 

esto es sólo una solución alternativa, pero pasé incontables horas sobre este tema y no pude encontrar una solución elegante.

22

Raphaël's answer es una excelente descripción del problema y una buena solución. Tuve exactamente el mismo problema y terminé arreglando con un indicador scrollingLocked que establecí en SÍ (bloqueado) antes de que se inicie la rotación, y NO (desbloqueado) cuando termina. Tal vez un poco menos hacky que cambiar temporalmente la contentSize:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation 
           duration:(NSTimeInterval)duration 
{ 
    self.photoViewer.scrollingLocked = YES; 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
{ 
    self.photoViewer.scrollingLocked = NO; 
} 

- (void)scrollViewDidScroll:(UIScrollView*)scrollView 
{ 
    if (self.scrollingLocked) 
    { 
     return; 
    } 
    /* do normal scrollViewDidScroll: stuff */ 
} 
+0

+1 para una respuesta correcta + más clara. –

+0

¿qué componente es el photoViewer? - porque no es un desplazamiento, ni una vista –

+2

@matheszabi, está usando un BOOL ivar para rastrear. Alternativamente, puede usar la propiedad incorporada 'scrollEnabled' de' UIScrollView'. Por cierto, esto todavía por alguna razón desencadena 'scrollViewDidScroll' cuando está en la última imagen. – Steven

0

Mi tarea es permitir el desplazamiento del paisaje. El diseño es para portait. Se me ocurrió una idea para agregar un ScrollView a los componentes, o en "Insertar en la vista de desplazamiento" en Interface Builder. He esperado que funcione, pero no. Estoy usando Xcode 4.4, iOS 5.1, (proyecto de oficina también necesita soporte para 4.2), pero el problema es el mismo.

En la pregunta sobre desbordamiento de pila iPhone SDK: UIScrollView does not scroll hay una fila que resuelve un problema.

Otro intento está en desbordamiento de pila pregunta iOS - UIScrollView is not working (it doesn't scroll at all - the image stays fixed), y esto me ayudó, junto con otros, por lo que aquí está mi portait-a-desplazable código paisaje:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
{ 
    if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){ 
     scrollView.contentSize = portaitScrollSize; 
    } 
    else{//statusbar is Landscape 
     scrollView.contentSize = landscapeScrollSize; 
    }  
} 

El ScrollView en unido a un Ivar ver en Interface Builder. portaitScrollSize y landscapeScrollSize son variables privadas. Se inicializan y no cambian.En my.h archivo:

IBOutlet UIScrollView *scrollView; 

En my.m archivo:

CGSize portaitScrollSize, landscapeScrollSize; 

...

portaitScrollSize = CGSizeMake(320,440); 
landscapeScrollSize = CGSizeMake(480,480); 

espero que ayudar a alguien a añadir una característica de desplazamiento + rotación a un diseño portait .

No se olvide de permitir que portait + paisaje en la componente superior:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return TRUE; 
} 
0

Además de la respuesta de Raphaël Mor. Si está cambiando de vertical a horizontal, el contenido y la estructura de la página se frenarán. Por lo tanto, con el fin de mantener la estructura de la página actual sólo tiene que añadir el tamaño de contenido extra para el ancho:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.contentSize.width + 400, self.scrollView.contentSize.height)]; 
} 

Y asegúrese de que establece la contentsize y compensar de nuevo después del cambio de orientación:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.bounds.size.width *3, self.scrollView.bounds.size.height)]; 
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width * self.pageControl.currentPage, 0) animated:NO]; 

} 
Cuestiones relacionadas