在用UICollectionView展示資料時,有時我們希望將cell的間距調成一個我們想要的值,然後查API可以看到有這麼一個屬性:
- (CGFloat)minimumInteritemSpacing { return 0;}
然而很多情況下我們會發現,這樣寫不能滿足我們的要求,cell之間仍然有一個不知道怎麼產生的間距。
我們知道cell的間距是由cell的大小itemSize和section的縮排sectionInset共同決定的,通過這兩個資料,UICollectionView動態地將cell放在相應的位置,然而即使我們接著調用inset方法也沒有用。
- (UIEdgeInsets)sectionInset{ return UIEdgeInsetsMake(0, 0, 0, 0);}
<註:我想實現的是0間距,其他情況類似>
可以看到,繼承UICollectionViewFlowLayout後在- layoutAttributesForElementsInRect:方法中列印一下這些cell的frame的結果
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{ NSMutableArray* attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; for (UICollectionViewLayoutAttributes *attr in attributes) { NSLog(@"%@", NSStringFromCGRect([attr frame])); }}
從上面兩行就可以看出來,我的高度是42.8,然而兩個cell的x值間距卻為46,也就是說有大約3px的間距。
其實,正如minimumInteritemSpacing的名字一樣,這個屬性設定的是間距的最小值,那麼,我們實際需要的應該是一個"maximumInteritemSpacing",也就是最大間距。要解決這個問題,需要自己做一些計算。
依舊是繼承UICollectionViewFlowLayout,然後在- layoutAttributesForElementsInRect:方法中添加如下代碼:
//從第二個迴圈到最後一個 for(int i = 1; i < [attributes count]; ++i) { //當前attributes UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i]; //上一個attributes UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1]; //我們想設定的最大間距,可根據需要改 NSInteger maximumSpacing = 0; //前一個cell的最右邊 NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame); //如果當前一個cell的最右邊加上我們想要的間距加上當前cell的寬度依然在contentSize中,我們改變當前cell的原點位置 //不加這個判斷的後果是,UICollectionView只顯示一行,原因是下面所有cell的x值都被加到第一行最後一個元素的後面了 if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) { CGRect frame = currentLayoutAttributes.frame; frame.origin.x = origin + maximumSpacing; currentLayoutAttributes.frame = frame; } }
原因注釋中已經解釋得非常詳細了。這樣就可以解決cell的間距問題了。再次運行,效果非常好: