4

Is it possible to restrict scrolling within a UICollectionView to a subset of the items in the collection?

I have a UICollectionView that displays one item at a time. Each item takes the full width of the screen. The user can scroll horizontally between items.

At times I want to be able to restrict the user to scrolling between a subset of items based on certain conditions.

For example, view may contain items 1 through 20, but I only want the user to be able to scroll between items 7 and 9.

I have tried changing the contentSize to just the width necessary to display the desired items, then changing the contentOffset, but this does not work.

Mike Taverne
  • 9,156
  • 2
  • 42
  • 58
  • you should return proper value in `- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section` and keep track of model objects you want to display somehow – kambala Jul 09 '14 at 18:11

2 Answers2

6

I spent like 6 hours researching this yesterday, but within minutes of posting my question I found the key to a solution here:

Cancel current UIScrollView touch

That answer describes how to cancel scrolling. What's neat is that the user doesn't see any scrolling behavior when they attempt to scroll outside the limits set for them; there is no flickering, nothing.

The solution I came up with is to determine the starting and ending offsets for the items I want the user to see, and then cancel scrolling in scrollViewDidScroll if the new offset is before the starting, or after the ending, offset:

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

    //Prevent user from scrolling to items outside the desired range
    if (scrollView.contentOffset.x < self.startingOffset ||
        scrollView.contentOffset.x > self.endingOffset) {
        scrollView.panGestureRecognizer.enabled = NO;
        scrollView.panGestureRecognizer.enabled = YES;
    }
}
Community
  • 1
  • 1
Mike Taverne
  • 9,156
  • 2
  • 42
  • 58
3

Swift version:

  override func scrollViewDidScroll(scrollView: UIScrollView) {
    //Prevent user from scrolling to items outside the desired range
    if (scrollView.contentOffset.x < self.startingOffset ||
      scrollView.contentOffset.x > self.endingOffset) {
        scrollView.panGestureRecognizer.enabled = false
        scrollView.panGestureRecognizer.enabled = true
    }
  }
fatihyildizhan
  • 8,614
  • 7
  • 64
  • 88