Adding padding to first and last cell of UICollectionView

slonkar picture slonkar · Aug 24, 2016 · Viewed 11.5k times · Source

I have subclassed UICollectionViewFlowLayout to get horizontal UICollectionView with paging like behavior. It works perfectly fine as long as UICollectionViewCell is not first of last cell. Images attached below.

enter image description here enter image description here

Do I need to override something in my UICollectionViewFlowLayout besides following ?

- (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;
}

Any pointers/ comments will be useful.

Answer

Ketan Parmar picture Ketan Parmar · Aug 24, 2016

You can set space at left and right equal to your padding when setting frame of your collection view.

or

You can put condition in cellForItemAtIndexPath that if it is first cell or last cell then manage padding accordingly. that's it.

Or

you can set contentInset property of your collectionView.

for example,

UICollectionView *cv; // your collectionView

cv.contentInset = UIEdgeInsetsMake(0, 5, 0, 5);

Alternatively, you can set the UICollectionView contentInset in storyboard to get it working.