UICollectionView 的布局默认是当前行内适应,如果cell的宽度超过当前的行宽度就会放到下一行,但是当前行内的多个cell会等距离分布,而不能像效果图中等间距靠left 或者right分布。
/// 让列间距固定为minimumInteritemSpacing
class AiUgcReportFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
if let attris = super.layoutAttributesForElements(in: rect) {
for (i, att) in attris.enumerated() {
if i>0 {
let cur = att
let pre = attris[i-1]
// 这里 indexPath 一定要判断,坑了半天,fuck
if cur.indexPath == pre.indexPath {
let preMaxX = pre.frame.maxX
//根据 maximumInteritemSpacing 计算出的新的 x 位置
let targetX = preMaxX + self.minimumInteritemSpacing;
if targetX < cur.frame.maxX && (targetX+cur.frame.width) < self.collectionViewContentSize.width {
var curFrame = cur.frame
curFrame.origin.x = targetX
cur.frame = curFrame
}
}
}
}
return attris
}
return super.layoutAttributesForElements(in: rect)
}
}
😀 😀 😀 😀 提供oc 版本,直接用吧骚年😀 😀 😀
- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attris = [super layoutAttributesForElementsInRect:rect];
for (int i = 0; i< attris.count; i++) {
if (i>0) {
UICollectionViewLayoutAttributes *curAtt = attris[i];
UICollectionViewLayoutAttributes *preAtt = attris[i-1];
// 这里 indexPath 一定要判断,坑了半天,fuck
if (curAtt.indexPath == preAtt.indexPath) {
CGFloat curMaxX = curAtt.frame.origin.x+curAtt.frame.size.width;
CGFloat preMaxX = preAtt.frame.origin.x+preAtt.frame.size.width;
CGFloat targetX = preMaxX + self.minimumInteritemSpacing;
if ((targetX < curMaxX) && (targetX+curAtt.frame.size.width) < self.collectionView.bounds.size.width) {
CGRect curFrame = curAtt.frame;
curFrame.origin.x = targetX;
curAtt.frame = curFrame;
}
}
}
}
return attris;
}