Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you determine spacing between cells in UICollectionView flowLayout

I have a UICollectionView with a flow layout and each cell is a square. How do I determine the spacing between each cells on each row? I can't seem to find the appropriate settings for this. I see there's a min spacing attributes on the nib file for a collection view, but I set this to 0 and the cells doesn't even stick.

enter image description here

Any other idea?

like image 314
adit Avatar asked Oct 22 '12 18:10

adit


People also ask

How do I change the spacing between cells in collection view?

I have found very easy way to configure spacing between cells or rows by using IB. Just select UICollectionView from storyboard/Xib file and click in Size Inspector as specified in below image. For configuring space programatically use following properties. 1) For setting space between rows.

What is UICollectionView flow layout?

Overview. A flow layout is a type of collection view layout. Items in the collection view flow from one row or column (depending on the scrolling direction) to the next, with each row containing as many cells as will fit. Cells can be the same sizes or different sizes.

How does UICollectionView work?

The collection view presents items onscreen using a cell, which is an instance of the UICollectionViewCell class that your data source configures and provides. In addition to its cells, a collection view can present data using other types of views.

What is Section inset?

Section insets are margins applied only to the items in the section. They represent the distance between the header view and the first line of items and between the last line of items and the footer view. They also indicate the spacing on either side of a single line of items.


1 Answers

Update: Swift version of this answer: https://github.com/fanpyi/UICollectionViewLeftAlignedLayout-Swift


Taking @matt's lead I modified his code to insure that items are ALWAYS left aligned. I found that if an item ended up on a line by itself, it would be centered by the flow layout. I made the following changes to address this issue.

This situation would only ever occur if you have cells that vary in width, which could result in a layout like the following. The last line always left aligns due to the behavior of UICollectionViewFlowLayout, the issue lies in items that are by themselves in any line but the last one.

With @matt's code I was seeing.

enter image description here

In that example we see that cells get centered if they end up on the line by themselves. The code below insures your collection view would look like this.

enter image description here

#import "CWDLeftAlignedCollectionViewFlowLayout.h"  const NSInteger kMaxCellSpacing = 9;  @implementation CWDLeftAlignedCollectionViewFlowLayout  - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {     NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect];     for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) {         if (nil == attributes.representedElementKind) {             NSIndexPath* indexPath = attributes.indexPath;             attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;         }     }     return attributesToReturn; }  - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {     UICollectionViewLayoutAttributes* currentItemAttributes =     [super layoutAttributesForItemAtIndexPath:indexPath];      UIEdgeInsets sectionInset = [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout sectionInset];      CGRect currentFrame = currentItemAttributes.frame;      if (indexPath.item == 0) { // first item of section         currentFrame.origin.x = sectionInset.left; // first item of the section should always be left aligned         currentItemAttributes.frame = currentFrame;          return currentItemAttributes;     }      NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];     CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;     CGFloat previousFrameRightPoint = CGRectGetMaxX(previousFrame) + kMaxCellSpacing;      CGRect strecthedCurrentFrame = CGRectMake(0,                                               currentFrame.origin.y,                                               self.collectionView.frame.size.width,                                               currentFrame.size.height);      if (!CGRectIntersectsRect(previousFrame, strecthedCurrentFrame)) { // if current item is the first item on the line         // the approach here is to take the current frame, left align it to the edge of the view         // then stretch it the width of the collection view, if it intersects with the previous frame then that means it         // is on the same line, otherwise it is on it's own new line         currentFrame.origin.x = sectionInset.left; // first item on the line should always be left aligned         currentItemAttributes.frame = currentFrame;         return currentItemAttributes;     }      currentFrame.origin.x = previousFrameRightPoint;     currentItemAttributes.frame = currentFrame;     return currentItemAttributes; }  @end 
like image 131
Chris Wagner Avatar answered Sep 19 '22 02:09

Chris Wagner