collectionView item莫名奇妙的间隙问题

最近项目中在做一个打卡的功能,用到了collection,但是界面渲染以后会发现有一个不知道怎么产生的间距,如图所示:但是我想实现的是所有的item间距为0,这里的itemSize为了以后扩展,设置为了ScreenWidth / kitemCount,minimuInteritemSpacing设置为0;

首先我们用view hierachy来看一下item的位置和大小
  • 没有间隙的俩个item


从俩张图的Position X可以看出俩个item的位置,因为Anchor point是0.5,所以显示的是图片中间的位置.第0个item是26.7857142857143,第一个item是80.2857142857143,俩者的间距是53,而item的width是53.57,比宽度小,所以没有间隙

  • 有间隙的俩个item

同理,第0个item是187.285714285714,第一个item是241.285714285714,俩者的间距是54,而item的width是53.57,比宽度大,所以有间隙


我们也可以通过代码打印item的frame来验证一下,自定义一个HFAdjustSpacingFlowLayout继承UICollectionViewFlowLayout,然后在-layoutAttributesForElementsInrect:方法打印这些Cell的frame信息,如图所示,item的x并没有随着item的大小递增,所以会出现间隙.验证了view hierarchy看到的结果.但是这些间隙怎么出现的,哪个大神知道了麻烦告诉一下.

解决方案

通过layoutAttributesForElementsInrect:方法中来修改item的frame来改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *original = [super layoutAttributesForElementsInRect:rect];
NSMutableArray *attributes = [[NSMutableArray alloc] initWithArray:original copyItems:YES];
//从第二个循环到最后一个,因为第一个不需要修改
for(int i = 1; i < [attributes count]; i++) {
//当前attributes
UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
//上一个attributes
UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
//设置的Cell间距,可根据需要改
NSInteger cellSpacing = 0;
//前一个cell的最右边
NSInteger prevCellRight = CGRectGetMaxX(prevLayoutAttributes.frame);
//如果当前一个cell的最右边加上我们想要的间距加上当前cell的宽度依然在contentSize中,我们改变当前cell的原点位置
//不加这个判断的后果是,UICollectionView只显示一行,原因是下面所有cell的x值都被加到第一行最后一个元素的后面了
if(prevCellRight + cellSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = prevCellRight + cellSpacing;
currentLayoutAttributes.frame = frame;
}
}
return attributes;
}

再次运行,效果如下:

这个人很帅<br>他什么都不想说<br>