如何确定 UICollectionView flowLayout 中单元格之间的间距 [英] How do you determine spacing between cells in UICollectionView flowLayout
问题描述
我有一个带有流布局的 UICollectionView,每个单元格都是一个正方形.如何确定每行每个单元格之间的间距?我似乎无法为此找到合适的设置.我看到 nib 文件上有一个用于集合视图的最小间距属性,但我将其设置为 0 并且单元格甚至不粘连.
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.
还有其他想法吗?
推荐答案
更新:此答案的 Swift 版本:https://github.com/fanpyi/UICollectionViewLeftAlignedLayout-Swift
Update: Swift version of this answer: https://github.com/fanpyi/UICollectionViewLeftAlignedLayout-Swift
以 @matt 的领导我修改了他的代码以确保项目始终左对齐.我发现如果一个项目自己结束在一行上,它会以流布局为中心.我进行了以下更改以解决此问题.
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.
只有当单元格宽度不同时才会发生这种情况,这可能导致布局如下.由于 UICollectionViewFlowLayout
的行为,最后一行总是左对齐,问题在于除最后一行之外的任何一行中的项目.
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.
我看到了@matt 的代码.
With @matt's code I was seeing.
在那个例子中,我们看到如果单元格自己最终在行上,则它们会居中.下面的代码确保您的集合视图看起来像这样.
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.
#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
这篇关于如何确定 UICollectionView flowLayout 中单元格之间的间距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!