Search code examples
iosobjective-cuicollectionviewuicollectionviewcelluicollectionviewlayout

Adding padding to first and last cell of UICollectionView


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.


Solution

  • 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.