Reputation: 4085
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.
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
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
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
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
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
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:
Upvotes: 11
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