Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting pull-up or dragging of UICollectionView

I am trying to come up with a way to automatically load the next page of images when user scrolls to the bottom of the first page of images in UICollectionView. UITableView (iOS 6) has refreshControl for similar purpose ("Pull to refresh") which can be used to refresh, or something similar. Is there a similar option available for UICollectionView?

Is there a way to detect that a UICollectionView is being dragged beyond the last line of cells, or if it is displaying the footer (which is below the last line of cells). This action can then be used to trigger my method to load the next page of images.

like image 219
kzia Avatar asked Sep 27 '13 21:09

kzia


3 Answers

Since collection views inherit from UIScrollView, you can implement scroll view delegate methods to detect the scroll motion. For instance, you can implement scrollViewDidScroll and use the contentOffset property to measure how far the user has scrolled down.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetY = scrollView.contentOffset.y;
    CGFloat contentHeight = scrollView.contentSize.height;
    if (offsetY > contentHeight - scrollView.frame.size.height)
    {
        //start loading new images
    }
}

Hope this helps!

like image 101
architectpianist Avatar answered Oct 22 '22 08:10

architectpianist


First we need to detect if the collection view has passed a certain scroll percentage and if it has, start loading the next page. See below:

//  Outside the implementation block:
static const CGFloat kNewPageLoadScrollPercentageThreshold = 0.66;

static BOOL ShouldLoadNextPage(UICollectionView *collectionView)
{
  CGFloat yOffset = collectionView.contentOffset.y;
  CGFloat height = collectionView.contentSize.height - CGRectGetHeight(collectionView.frame);
  return yOffset / height > kNewPageLoadScrollPercentageThreshold;
}

//  Inside the implementation block:    
#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView 
  didEndDisplayingCell:(UICollectionViewCell *)cell 
    forItemAtIndexPath:(NSIndexPath *)indexPath
{
  BOOL shouldLoadNextPage = ShouldLoadNextPage(collectionView);
  if (shouldLoadNextPage && !_pageLoading) {
    [self _loadNextPage];
  }
}
like image 37
Zorayr Avatar answered Oct 22 '22 08:10

Zorayr


Another option is to simply load the next image or set of images once a specific cell is requested. For example, if you just want to make sure you are preloading images 10 at a time...

if (indexPath.row % 10 == 0)
    [self preloadImagesStartingAt:indexPath.row + 10 count:10];

The preload method would then do nothing if the images have been requested or exist, or initiate a request.

like image 36
Matt Avatar answered Oct 22 '22 07:10

Matt