slonkar
slonkar

Reputation: 4085

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.

Upvotes: 27

Views: 17817

Answers (6)

Javidan
Javidan

Reputation: 1

You can use this piece of code for padding

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    return UIEdgeInsets(top: 60, left: 0, bottom: 40, right: 0)
}

Upvotes: 0

Ketan Parmar
Ketan Parmar

Reputation: 27438

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.

Upvotes: 57

Tung Fam
Tung Fam

Reputation: 8157

Accepted solution works but if you have pagingEnabled the collection view paging gets broken.

For me the solution was to use:


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
}

Upvotes: 9

Rbar
Rbar

Reputation: 3928

For Swift 5:

In your viewDidLoad, set contentInset property of the collectionView like so:

self.collectionView.contentInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);

Upvotes: 4

Jonathan Cabrera
Jonathan Cabrera

Reputation: 1751

You can achieve that by changing the insets from the Interface Builder. They can be found as Section Insets in the Size Inspector:

Section Insets for Collection View in InterfaceBuilder

Upvotes: 11

Pankaj K.
Pankaj K.

Reputation: 535

simple you can use collectionview methods to set UIEdgeInsets like bellow method.

-(UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
  return UIEdgeInsetsMake(0,10,0,10); // top, left, bottom, right
}

here you can pass the value for left side space and right side space for first and last cell, you can also provide minimum space between two cell through bellow method

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
   return 5.0;
}

Upvotes: 3

Related Questions