2010-08-29 17 views
3

Je rencontre des problèmes lors de l'utilisation d'un UIScrollView sur l'iPhone lors de la rotation. J'ai utilisé l'exemple PageControl d'Apple comme modèle, mais je crée moi-même le scrollview dans une vue.Problèmes lors de la rotation de UIScrollView avec la pagination

1) Le scrollview fonctionne comme prévu lors du chargement en défaut Portrait, le défilement de gauche à droite horizontalement

2) Hors de la boîte, lors de la rotation CW et réinitialisant tourne la plupart du temps sur le côté et il tourne maintenant verticalement vers le bas au lieu de l'horizontal désiré. Il semble que la largeur/hauteur du cadre de défilement ne change pas, juste l'orientation de lui-même.

3) J'ai essayé d'ajouter une logique de détection d'orientation pour dimensionner et feuilleter correctement le scrollview en fonction de l'orientation qui a fonctionné, mais seulement si je fais pivoter CCW en paysage. Si je vais en CW, il commence à droite et fait défiler vers la gauche, et les choses ne marchent pas.

De toute évidence, cela devient de plus en plus difficile, alors existe-t-il un moyen approprié de configurer mon UIScrollview et de le réintroduire avec des rotations de sorte qu'il défile toujours de gauche à droite?


- (void)loadView { 
    [self setupPage]; 
} 

-(void) setupPage { 
    // lazy init view controllers 
    NSMutableArray *controllers = [[NSMutableArray alloc] init]; 
    for (unsigned i = 0; i = kNumberOfPages) return; 

    // replace the placeholder if necessary 
    MyViewController *controller = [viewControllers objectAtIndex:page]; 
    if ((NSNull *)controller == [NSNull null]) { 
     controller = [[MyViewController alloc] initWithPageNumber:page]; 
     [viewControllers replaceObjectAtIndex:page withObject:controller]; 
     [controller release]; 
    } 

    // add the controller's view to the scroll view 
    if (nil == controller.view.superview) { 
     CGRect frame = scrollView.frame; 

     int x = 0; 
     int y = 0; 
     UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
     if(orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){ 
      x = 0; 
      y = frame.size.height * page; 
     } else { 
      x = frame.size.width * page; 
      y = 0; 
     } 

     frame.origin.x = x; 
     frame.origin.y = y; 
     controller.view.frame = frame; 
     [scrollView addSubview:controller.view]; 
    } 
} 

- (void)scrollViewDidScroll:(UIScrollView *)sender { 
    // We don't want a "feedback loop" between the UIPageControl and the scroll delegate in 
    // which a scroll event generated from the user hitting the page control triggers updates from 
    // the delegate method. We use a boolean to disable the delegate logic when the page control is used. 
    if (pageControlUsed) { 
     // do nothing - the scroll was initiated from the page control, not the user dragging 
     return; 
    } 

    // Switch the indicator when more than 50% of the previous/next page is visible 
    CGFloat pageWidth = scrollView.frame.size.width; 
    int offset = 0; 
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
    if(orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){ 
     pageWidth = scrollView.frame.size.height; 
     offset = scrollView.contentOffset.y; 
    } else { 
     pageWidth = scrollView.frame.size.width; 
     offset = scrollView.contentOffset.x ; 
    } 

    //CGFloat pageWidth = scrollView.frame.size.width; 
    int page = floor((offset - pageWidth/2)/pageWidth) + 1; 
    pageControl.currentPage = page; 

    // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling) 
    [self loadScrollViewWithPage:page - 1]; 
    [self loadScrollViewWithPage:page]; 
    [self loadScrollViewWithPage:page + 1]; 

    // A possible optimization would be to unload the views+controllers which are no longer visible 
} 

// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    pageControlUsed = NO; 
} 

// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    pageControlUsed = NO; 
} 


- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    [self setupPage]; 
} 
 

Répondre

2

Vous n'êtes pas changer le contentSize de votre scrollview, alors quand il tourne, il ne sait pas qu'il est plus large que plus grand.

En outre, comme un raccourci, chaque VC a une propriété interfaceOrientation déjà défini, et il y a des fonctions intégrées pour détecter l'orientation: UIInterfaceOrientationIsPortrait (self.interfaceOrientation) et UIInterfaceOrientationIsLandscape (self.interfaceOrientation). Enfin, juste une chose visuelle, en utilisant willRotateToInterfaceOrientation: la durée est un peu plus agréable sur les yeux, et l'utilisateur ne perçoit jamais un changement car il arrive presque simultanément à la rotation.