2009-06-08 5 views
1

Avertissement: Ceci est mon premier iPhone application donc il y a beaucoup de programmes de culte du cargo qui se passe ici. J'ai cherché sur google google, testé stackoverflow, lu des livres, et changé le code encore et encore dans une tentative de résoudre ce problème et je ne peux pas. J'utilise la classe PageScrollView trouvée dans "iPhone SDK Application Development" par Jonathan Zdziarski. C'est une classe qui fournit une vue de 5 images (ou plus), chargeant 3 en mémoire en même temps. Je veux 3 de ces PageScrollViews sur l'écran à la fois empilés les uns sur les autres. Une rangée supérieure de 5 images pour défiler horizontalement, une rangée d'images pour défiler horizontalement et une rangée d'images pour défiler horizontalement pendant que le téléphone est en position portrait. Je change complètement de vue en mode paysage . PageScrollView tel que modifié par moi, tout ce qui a été commenté était à un moment donné décommenté dans une tentative de faire ce travail. J'ai essayé de commenter autant que je pouvais pour isoler le problème:PageScrollViews multiples (UIScrollViews) sur l'écran à la fois (non imbriquée)

#import "PageScrollView.h" 

@implementation PageScrollView 

-(id)initWithFrame:(CGRect)frame { 
    self = [ super initWithFrame: frame ]; 
    if (self != nil) { 
     _pages = nil; 
     _zeroPage = 0; 
     _pageRegion = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); 
     //_controlRegion = CGRectMake(frame.origin.x,frame.size.height/2, frame.size.width, 0); 

     self.delegate = nil; 

     scrollView = [ [ UIScrollView alloc ] initWithFrame: _pageRegion ]; 
     scrollView.pagingEnabled = YES; 
     scrollView.delegate = self; 
     [ scrollView setContentOffset: CGPointMake(frame.origin.x, frame.origin.y) ]; 
     [ scrollView setContentSize: CGSizeMake(_pageRegion.size.width,_pageRegion.size.height) ]; 
     [ scrollView setContentInset : UIEdgeInsetsMake(0.0,80.0,0,0) ]; 
     [ self addSubview: scrollView ]; 

     //pageControl = [ [ UIPageControl alloc ] initWithFrame: _controlRegion ]; 
     //[ pageControl addTarget: self action: @selector(pageControlDidChange:) forControlEvents: UIControlEventValueChanged ]; 
     //[ self addSubview: pageControl ]; 
    } 
    return self; 
} 

-(void)setPages:(NSMutableArray *)pages { 
    if (pages != nil) { 
     for(int i=0;i<[_pages count];i++) { 
      [ [ _pages objectAtIndex: i ] removeFromSuperview ]; 
     } 
    } 
    _pages = pages; 
    //scrollView.contentOffset = CGPointMake(0.0, 0.0); 
    scrollView.contentOffset = CGPointMake(0.0, _pageRegion.origin.y); 
    if ([ _pages count] < 3) { 
     scrollView.contentSize = CGSizeMake(_pageRegion.size.width * [ _pages count ], _pageRegion.size.height); 
    } else { 
     scrollView.contentSize = CGSizeMake(_pageRegion.size.width * 3, _pageRegion.size.height); 
     scrollView.showsHorizontalScrollIndicator = NO; 
    } 
    pageControl.numberOfPages = [ _pages count ]; 
    pageControl.currentPage = 0; 
    [ self layoutViews ]; 
} 

- (void)layoutViews { 
    if ([ _pages count ] <= 3) { 
     for(int i=0;i<[ _pages count];i++) { 
      UIView *page = [ _pages objectAtIndex: i ]; 
      //CGRect bounds = page.bounds; 
      //CGRect frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      //CGRect frame = CGRectMake(_pageRegion.size.width * i, _pageRegion.origin.y+_pageRegion.size.height , _pageRegion.size.width, _pageRegion.size.height); 
      //page.frame = frame; 
      //page.bounds = bounds; 
      [ scrollView addSubview: page ]; 
     } 
     return; 
    } 

    /* For more than 3 views, add them all hidden, layout according to page */ 
    for(int i=0;i<[ _pages count];i++) { 
     UIView *page = [ _pages objectAtIndex: i ]; 
     //CGRect bounds = page.bounds; 
     //CGRect frame = CGRectMake(0.0, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
     //CGRect frame = CGRectMake(0.0, _pageRegion.origin.y+_pageRegion.size.height, _pageRegion.size.width, _pageRegion.size.height); 
     //page.frame = frame; 
     //page.bounds = bounds; 
     page.hidden = YES; 
     [ scrollView addSubview: page ]; 
    } 
    [ self layoutScroller ]; 
} 

- (void)layoutScroller { 
    UIView *page; 
    CGRect bounds, frame; 
    int pageNum = [ self getCurrentPage ]; 

    if ([ _pages count ] <= 3) 
     return; 

    NSLog(@"Laying out scroller for page %d\n", pageNum); 

    /* Left boundary */ 
    if (pageNum == 0) { 
     for(int i=0;i<3;i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      //frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      frame = CGRectMake(_pageRegion.size.width * i, 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     page = [ _pages objectAtIndex: 3 ]; 
     page.hidden = YES; 
     _zeroPage = 0; 
    } 

    /* Right boundary */ 
    else if (pageNum == [ _pages count ] -1) { 
     for(int i=pageNum-2;i<=pageNum;i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      frame = CGRectMake(_pageRegion.size.width * (2-(pageNum-i)), 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     page = [ _pages objectAtIndex: [ _pages count ]-3 ]; 
     page.hidden = YES; 
     _zeroPage = pageNum - 2; 
    } 

    /* All middle pages */ 
    else { 
     for(int i=pageNum-1; i<=pageNum+1; i++) { 
      page = [ _pages objectAtIndex: i ]; 
      bounds = page.bounds; 
      frame = CGRectMake(_pageRegion.size.width * (i-(pageNum-1)), 0.0, _pageRegion.size.width, _pageRegion.size.height); 
      NSLog(@"\tOffset for Page %d = %f\n", i, frame.origin.x); 
      page.frame = frame; 
      page.bounds = bounds; 
      page.hidden = NO; 
     } 
     for(int i=0; i< [ _pages count ]; i++) { 
      if (i < pageNum-1 || i > pageNum + 1) { 
       page = [ _pages objectAtIndex: i ]; 
       page.hidden = YES; 
      } 
     } 
     //scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0); 
     scrollView.contentOffset = CGPointMake(_pageRegion.size.width, 0.0); 
     _zeroPage = pageNum-1; 
    } 
} 

-(id)getDelegate { 
    return _delegate; 
} 

- (void)setDelegate:(id)delegate { 
    _delegate = delegate; 
} 

-(BOOL)getShowsPageControl { 
    return _showsPageControl; 
} 

-(void)setShowsPageControl:(BOOL)showsPageControl { 
    _showsPageControl = showsPageControl; 
    if (_showsPageControl == NO) { 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 
     pageControl.hidden = YES; 
     scrollView.frame = _pageRegion; 
    } else { 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height - 60.0); 
     //_pageRegion = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 
     pageControl.hidden = NO; 
     scrollView.frame = _pageRegion; 
    } 
} 

-(NSMutableArray *)getPages { 
    return _pages; 
} 

-(void)setCurrentPage:(int)page { 
// [ scrollView setContentOffset: CGPointMake(0.0, 0.0) ]; 
    [ scrollView setContentOffset: CGPointMake(0.0,_pageRegion.origin.y) ]; 
    _zeroPage = page; 
    [ self layoutScroller ]; 
    pageControl.currentPage = page; 
} 

-(int)getCurrentPage { 
    return (int) (scrollView.contentOffset.x/_pageRegion.size.width) + _zeroPage; 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    pageControl.currentPage = self.currentPage; 
    [ self layoutScroller ]; 
    [ self notifyPageChange ]; 
} 

-(void) pageControlDidChange: (id)sender 
{ 
    UIPageControl *control = (UIPageControl *) sender; 
    if (control == pageControl) { 
     //[ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ]; 
     [ scrollView setContentOffset: CGPointMake(_pageRegion.size.width * (control.currentPage - _zeroPage), 0.0) animated: YES ]; 

    } 
} 

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
     [ self layoutScroller ]; 
     [ self notifyPageChange ]; 
} 

-(void) notifyPageChange { 
    if (self.delegate != nil) { 
//  if ([ _delegate conformsToProtocol:@protocol(PageScrollViewDelegate) ]) { 
      if ([ _delegate respondsToSelector:@selector(pageScrollViewDidChangeCurrentPage:currentPage:) ]) { 
       [ self.delegate pageScrollViewDidChangeCurrentPage: (PageScrollView *)self currentPage: self.currentPage ]; 
      } 
//  } 
    } 
} 

@end 

Voici ma méthode de loadview de ma classe ViewController:

- (void)loadView { 
    [ super loadView ]; 

    /* Load demo images for pages */ 
    topPages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ topPages addObject: page ];  
    } 

    CGRect viewBounds = [ [ UIScreen mainScreen ] applicationFrame ]; 
    viewBounds.origin.y = 0.0; 

    portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ]; 
    portraitTopView.pages = topPages; 
    portraitTopView.delegate = self; 
    //portraitTopView.showsPageControl = NO; 

    middlePages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ middlePages addObject: page ]; 
    } 

    portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ]; 
    portraitMiddleView.pages = middlePages; 
    portraitMiddleView.delegate = self; 
    //portraitMiddleView.showsPageControl = NO; 

    bottomPages = [ [ NSMutableArray alloc ] init ]; 
    for(int i = 0; i < 5; i++) { 
     UIImage *image = [ [ UIImage alloc ] initWithData: [ NSData dataWithContentsOfURL: [ NSURL URLWithString: [ NSString stringWithFormat: @"http://www.zdziarski.com/demo/%d.png", i+1 ] ] ] ]; 
     UIImageView *page = [ [ UIImageView alloc ] initWithFrame: CGRectMake(0,0,320,160) ] ; 
     page.image = image; 
     //page.bounds = CGRectMake(0.0, 0.0, 320, 160); 
     [ bottomPages addObject: page ];   
    } 

    portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ]; 
    portraitBottomView.pages = bottomPages; 
    portraitBottomView.delegate = self; 
    //portraitBottomView.showsPageControl = NO; 


    portraitView = [ [ UIView alloc ] initWithFrame: viewBounds ]; 
    [ portraitView addSubview: portraitTopView ]; 
    [ portraitView addSubview: portraitMiddleView ]; 
    [ portraitView addSubview: portraitBottomView ]; 

    landscapeTextView = [ [ UITextView alloc ] initWithFrame: viewBounds ]; 
    landscapeTextView.text = woahDizzy; 

    self.view = portraitView; 
} 

Mon problème est que les zones de défilement (les parties de l'écran que je touche) ne semble pas correspondre aux images. Pour obtenir les images à afficher correctement, j'utilise:

portraitTopView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,0,320,160) ]; 
portraitMiddleView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,80,320,160) ]; 
portraitBottomView = [ [ PageScrollView alloc ] initWithFrame: CGRectMake(0,160,320,160) ]; 

Cependant, ces chiffres ne me semblent pas corrects. Je pense que les valeurs de y devraient être respectivement de 0,160 et 320 parce que j'ai 3 images de 160 pixels de haut chacune (3x160 = 480), mais lorsque je mets les valeurs y à 0,160 et 320 l'image supérieure est au sommet de l'écran, l'image du milieu est où l'image du bas devrait être et l'image du bas est loin de l'écran. Mais quand j'ai les valeurs y fixées à 0,80 et 160 les images s'affichent correctement, mais les zones de défilement fonctionnent (j'ai l'intuition que les zones de défilement ou les zones tactiles sont appelées au-dessus des images).

Quelqu'un a-t-il des idées?

Répondre

1

Je pense que les choses pourraient être beaucoup plus facile si vous ne l'avez pas essayer de construire manuellement la mise en page. Jetez un coup d'œil à ceci:

Créer votre UIScrollView (viewBase est une instance de UIScrollView)

int imgWidth = 160; 
int numImages = 3; 
int scrollWidth = imgWidth * numImages; 

int imgHeight = 160; 
int numRows = 3; 
int scrollHeight = imgHeight * numRows; 

viewBase.contentSize = CGSizeMake(scrollWidth, scrollHeight); 
// Set anything else you need on viewbase 

Ensuite, lorsque vous ajoutez vos éléments à la UIScrollView, faire des calculs similaires.

// Add this View to the far left of the scroller. 
webViewOne = [[UIWebView alloc] initWithFrame: CGRectMake(viewBase.frame.origin.x, viewBase.frame.origin.y, viewBase.frame.size.width, viewBase.frame.size.height)]; 
[viewBase addSubview:webViewOne]; 
[webViewOne release]; 

// Add this View tot he right of webViewOne (Note the offset on the X coordinate) 
webViewTwo = [[UIWebView alloc] initWithFrame: CGRectMake((viewBase.frame.size.width * 1), viewBase.frame.origin.y, viewBase.frame.size.width, viewBase.frame.size.height)]; 
[viewBase addSubview:webViewTwo]; 
[webViewTwo release]; 

Cela permet à tous le dimensionnement et la disposition d'être par rapport à la UIScrollView sous-jacente plutôt que d'essayer de contrôler pixel par pixel les choses.

+0

Cela permettra-t-il de faire défiler indépendamment 3 rangées d'images? Je veux être en mesure de voir l'image 1 dans la rangée du haut, l'image 3 dans la rangée du milieu et l'image 2 dans la rangée du bas, ou toute autre combinaison. J'essayais aussi d'utiliser PageScrollView parce que j'aurais des centaines d'images. –

+0

Oui, l'UIScrollView est juste une grande "toile". Vous définissez les éléments à l'aide de calculs et de pixels. Le code ci-dessus crée une UIScrollView qui est deux fois la largeur de l'écran d'un appareil et définit ensuite deux UIWebViews côte à côte (en compensant la parcelle sur l'axe X du second point de vue. En décalant le X et l'intrigue Y, vous créer des colonnes et des lignes. Il vous suffit d'être en mesure de suivre les taches sur la « grille » virtuel que vous créez. C'est pourquoi j'ai créé des variables pour la largeur, la hauteur, etc ... Plus facile à suivre votre mise en page. Je pense que je – MystikSpiral

+0

trouver.Vous suggérez une grande toile avec 3 cadres mobiles horizontalement indépendamment de mon 1 cadre statique avec 3 toiles en mouvement? J'aime l'idée, mais je ne comprends pas vraiment comment vous contourner le problème de la mémoire de charger des centaines d'images à la fois? –

Questions connexes