Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: ScrollView infinite paging - Duplicate end caps

I have a question about infinite paging in a ScrollView. In my app I have only 3 subviews in ScrollView. Each subview is loaded from xib file. Normally it looks like ABC in ScrollView. I wanted to make infinite paging so I added end caps and now it looks like CABCA. If the user is on the first C, it jumps to regular C and if user is on the last A, it jumps to regular A. Here is a code:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {

  if (scrollView.contentOffset.x == 0)
  {
      [scrollView scrollRectToVisible:CGRectMake
      ((scrollView.frame.size.width * 3), 0,
      scrollView.frame.size.width,
      scrollView.frame.size.height) animated:NO];
  } 
  else if (scrollView.contentOffset.x == scrollView.frame.size.width * 4)
  {
     [scrollView scrollRectToVisible:CGRectMake
     (scrollView.frame.size.width, 0,
      scrollView.frame.size.width,
      scrollView.frame.size.height) animated:NO];
   }
}

It works perfectly now. But I have ViewController for each subview and this is how I am adding them to ScrollView:

  subViewController1 = [[SubViewController1 alloc] initWithNibName:@"SubView" bundle:nil];
  subViewController1.view.frame =
    CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
  [scrollView addSubview:subViewController1.view];

Problem is that there is one duplicate of A and C view so now I have 5 controllers instead of 3. And If I want to add something into a A view, I have to add it also into duplicate of A view.

Is there a way how to control view A and duplicate of A with one controller so I don't have to create two instances of one controller? Thank you.

like image 657
DanielH Avatar asked May 28 '13 09:05

DanielH


1 Answers

Better still, you don't need to have duplicate view A's and duplicate view C's, you just move them around in - (void)scrollViewDidScroll:(UIScrollView *)scrollView while manipulating the contentOffset.

Setup: probably very similar to how you already do it.

Set your UIScrollView to have contentSize 3 times it's bounds width. Make sure paging is turned on and bouncing off.

Add your ABC subviews to the UIScrollView from left to right.

Also have an array in your ViewController called _contentViews that contains your UIViews ABC.

Then implement this which will reset the content offset and move your subviews around at the same time when the scrollview reaches the edges:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {

    if(scrollView.contentOffset.x == 0) {
        CGPoint newOffset = CGPointMake(scrollView.bounds.size.width+scrollView.contentOffset.x, scrollView.contentOffset.y);
        [scrollView setContentOffset:newOffset];
        [self rotateViewsRight];
    }
    else if(scrollView.contentOffset.x == scrollView.bounds.size.width*2) {
        CGPoint newOffset = CGPointMake(scrollView.contentOffset.x-scrollView.bounds.size.width, scrollView.contentOffset.y);
        [scrollView setContentOffset:newOffset];
        [self rotateViewsLeft];
    }
}

-(void)rotateViewsRight {
    UIView *endView = [_contentViews lastObject];
    [_contentViews removeLastObject];
    [_contentViews insertObject:endView atIndex:0];
    [self setContentViewFrames];

}

-(void)rotateViewsLeft {
    UIView *endView = _contentViews[0];
    [_contentViews removeObjectAtIndex:0];
    [_contentViews addObject:endView];
    [self setContentViewFrames];

}

-(void) setContentViewFrames {
    for(int i = 0; i < 3; i++) {
        UIView * view = _contentViews[i];
        [view setFrame:CGRectMake(self.view.bounds.size.width*i, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    }
}
like image 185
Mike Pollard Avatar answered Nov 11 '22 09:11

Mike Pollard