Skip to content

Instantly share code, notes, and snippets.

@rkeniger
Created November 28, 2013 04:33

Revisions

  1. rkeniger created this gist Nov 28, 2013.
    66 changes: 66 additions & 0 deletions gistfile1.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
    CGFloat offSetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = (CGFloat) (proposedContentOffset.x + (self.collectionView.bounds.size.width / 2.0));

    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    NSArray *array = [self layoutAttributesForElementsInRect:targetRect];
    for (UICollectionViewLayoutAttributes *layoutAttributes in array)
    {
    if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
    {
    CGFloat itemHorizontalCenter = layoutAttributes.center.x;
    if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offSetAdjustment))
    {
    offSetAdjustment = itemHorizontalCenter - horizontalCenter;
    }
    }
    }

    CGFloat nextOffset = proposedContentOffset.x + offSetAdjustment;

    do {
    proposedContentOffset.x = nextOffset;
    CGFloat deltaX = proposedContentOffset.x - self.collectionView.contentOffset.x;
    CGFloat velX = velocity.x;

    if(deltaX == 0.0 || velX == 0 || (velX > 0.0 && deltaX > 0.0) || (velX < 0.0 && deltaX < 0.0))
    {
    break;
    }

    if(velocity.x > 0.0)
    {
    nextOffset += [self snapStep];
    }
    else if(velocity.x < 0.0)
    {
    nextOffset -= [self snapStep];
    }
    } while ([self isValidOffset:nextOffset]);

    proposedContentOffset.y = 0.0;

    return proposedContentOffset;
    }

    - (BOOL)isValidOffset:(CGFloat)offset
    {
    return (offset >= [self minContentOffset] && offset <= [self maxContentOffset]);
    }

    - (CGFloat)minContentOffset
    {
    return -self.collectionView.contentInset.left;
    }

    - (CGFloat)maxContentOffset
    {
    return [self minContentOffset] + self.collectionView.contentSize.width - self.itemSize.width;
    }

    - (CGFloat)snapStep
    {
    return self.itemSize.width + self.minimumLineSpacing;
    }