2010-11-08 6 views
18

J'utilise UIScrollView et une image en tant que pagination d'une image par page. J'ai un problème lors de la rotation du iPhoneUIScrollView désactive le défilement lors de la rotation sur l'iPhone/iPad

Lorsque je fais pivoter l'iPhone, scrollViewDidScroll (méthode Scroll view delegate) est en cours d'appel. Pour cette raison, ma recherche est perturbée et le numéro de page change.

Quelle est la solution?

+0

ayant la même question. .., avez-vous réussi à résoudre le problème? – negersiu

+1

@ Maciulis..Que exactement j'ai été fait à ce moment ... mais je vérifie le code .. et je n'utilise pas la méthode scrollViewDidScroll et en utilisant scrollViewDidEndDecelerating .. et d'utiliser une variable globale pour le numéro de page en cours .. espérons que ce sera vous aider ou dites-moi exactement ce que vous voulez –

Répondre

13

J'ai trouvé un comportement non documenté étrange lors de la rotation d'un UIScrollView paginé. Lorsque la vue défilante est positionnée à la dernière page et que l'utilisateur change d'orientation, le système d'exploitation fait défiler UIScrollView vers l'arrière pour compenser la différence entre la hauteur et la largeur.

Fondamentalement, j'ai reçu les appels suivants pour n'importe quelle page.

willRotateToInterfaceOrientation:duration 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

Et pour la dernière page:

willRotateToInterfaceOrientation:duration 
scrollViewDidScroll: 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

Ce foiré avec mes pages aussi. Le problème est que dans willRotate, les limites ne sont pas mis à jour par le système d'exploitation encore, et willAnimate vous avez les nouvelles limites et peut calculer la nouvelle taille, mais il est trop tard ...

- (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]; 
} 

Ceci est juste une solution de contournement, mais j'ai passé d'innombrables heures sur cette question et ne pouvais pas trouver une solution élégante.

22

Raphaël's answer est une excellente description du problème, et une solution soignée. J'ai eu exactement le même problème et j'ai fini par corriger avec un drapeau scrollingLocked que j'ai défini sur OUI (verrouillé) avant le début de la rotation, et NON (déverrouillé) quand il se termine. Peut-être un peu moins hacky que de changer temporairement le 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 pour une réponse correcte + plus claire. –

+0

Quel composant est le photoViewer? - parce que ce n'est pas un parchemin, ni une vue –

+2

@matheszabi, il utilise un BOAR ivar pour suivre. Alternativement, vous pouvez simplement utiliser la propriété intégrée 'scrollEnabled' de' UIScrollView'. À propos, cela déclenche encore pour une raison quelconque 'scrollViewDidScroll' quand sur la dernière image. – Steven

0

Ma tâche est de permettre le défilement du paysage. Le design est pour le portrait. Je suis venu avec une idée pour ajouter un ScrollView aux composants, ou dans "Embed in Scroll View" dans Interface Builder. Je m'attendais à ce que cela fonctionne, mais non. J'utilise Xcode 4.4, iOS 5.1, (le projet de bureau a besoin du support pour 4.2 aussi), mais le problème est le même.

Dans la question de débordement de pile iPhone SDK: UIScrollView does not scroll Il y a une ligne qui résout un problème.

Autre essai est Stack Overflow question iOS - UIScrollView is not working (it doesn't scroll at all - the image stays fixed), et cela m'a aidé, combinée à d'autres, alors voici ma Portait-à-scrollable code paysage:

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

Le ScrollView dans lié à un iVar vue dans Interface Builder. portaitScrollSize et landscapeScrollSize sont des variables privées. Ils sont initialisés et ne changent pas. Dans my.h fichier:

IBOutlet UIScrollView *scrollView; 

Dans le fichier my.m:

CGSize portaitScrollSize, landscapeScrollSize; 

...

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

J'espère que cela aidera quelqu'un d'ajouter une fonction de défilement + rotation à une conception Portait .

Ne pas oublier de laisser Portait + paysage sur l'élément supérieur :

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

En plus de la réponse de Raphaël Mor. Si vous passez du mode portrait au mode paysage, le contenu et la structure de la page vont freiner. Par conséquent, afin de maintenir la structure actuelle de la page ajouter simplement la taille du contenu supplémentaire à la largeur:

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

Et assurez-vous de régler la contentSize et offset à nouveau après l'orientation a changé:

- (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]; 

} 
Questions connexes