在用UICollectionView展示数据时,有时我们希望将cell的间距调成一个我们想要的值,但是往往在不同设备上显示的却不能达到预期的效果。
cell的间距是由cell的大小itemSize和section的缩进sectionInset共同决定的。可以通过UICollectionViewFlowLayout的子类对cell进行约束。
如:
@interface QQSquareCollectionViewFlowLayout : UICollectionViewFlowLayout
/**
* 初始化UICollectionViewFlowLayout对象实例
* @param sectionInset 布局的内边距
* @param interitemSpacing 列间距
* @param lineSpacing 行间距
* @param itemSize 每个item的大小
* @return 返回的对象实例
*/
- (instancetype)initWithSectionInset:(UIEdgeInsets)sectionInset interitemSpacing:(CGFloat)interitemSpacing lineSpacing:(CGFloat)lineSpacing itemSize:(CGSize)itemSize;
@end
#import "QQSquareCollectionViewFlowLayout.h"
@interface QQSquareCollectionViewFlowLayout ()
/*列间距*/
@property (nonatomic, assign) CGFloat interitemSpacing;
/*行间距*/
@property (nonatomic, assign) CGFloat lineSpacing;
@end
@implementation QQSquareCollectionViewFlowLayout
#pragma mark - 初始化UICollectionViewFlowLayout对象实例
- (instancetype)initWithSectionInset:(UIEdgeInsets)sectionInset interitemSpacing:(CGFloat)interitemSpacing lineSpacing:(CGFloat)lineSpacing itemSize:(CGSize)itemSize {
self = [super init];
if (self) {
self.sectionInset = sectionInset;
self.minimumInteritemSpacing = 0.f;
self.minimumLineSpacing = lineSpacing;
self.itemSize = itemSize;
_interitemSpacing = interitemSpacing;
_lineSpacing = lineSpacing;
}
return self;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attributesArray = [super layoutAttributesForElementsInRect:rect];
UICollectionViewLayoutAttributes *firstLayoutAttributes = [attributesArray firstObject];
firstLayoutAttributes.frame = CGRectMake(self.sectionInset.left, firstLayoutAttributes.frame.origin.y, firstLayoutAttributes.frame.size.width, firstLayoutAttributes.frame.size.height);
for(NSUInteger i = 1; i < attributesArray.count; ++i) {
//当前attributes
UICollectionViewLayoutAttributes *currentLayoutAttributes = attributesArray[i];
//上一个attributes
UICollectionViewLayoutAttributes *prevLayoutAttributes = attributesArray[i - 1];
CGRect prevFrame = prevLayoutAttributes.frame;
//前一个cell的最右边
CGFloat prevMaxX = CGRectGetMaxX(prevFrame);
//我们想设置的最大列间距 self.minimumLineSpacing
//如果当前一个cell的最右边加上我们想要的间距加上当前cell的宽度依然在contentSize中,我们改变当前cell的原点位置
//不加这个判断的后果是,UICollectionView只显示一行,原因是下面所有cell的x值都被加到第一行最后一个元素的后面了
if(prevMaxX + self.interitemSpacing + currentLayoutAttributes.frame.size.width + self.sectionInset.right <= self.collectionViewContentSize.width) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = prevMaxX + self.interitemSpacing;
currentLayoutAttributes.frame = frame;
}
}
return attributesArray;
}
在控制器中使用:
/*每个九宫格之间的间隙*/
#define kSpace 15.f
/*九宫格排几列*/
#define kColumn 2
- (UICollectionView *)collectionView {
if (!_collectionView) {
CGFloat space = QQHorizontalRatioValue(kSpace);
//设置布局的内边距
UIEdgeInsets sectionInset = UIEdgeInsetsMake(space, space, space, space);
//设置列间距
CGFloat interitemSpacing = space;
//设置行间距
CGFloat lineSpacing = space;
//设置每个item的大小
CGFloat itemWidth = (self.view.bounds.size.width - sectionInset.left - sectionInset.right - interitemSpacing * (kColumn - 1)) / kColumn;
CGFloat itemHeight = itemWidth;
CGSize itemSize = CGSizeMake(itemWidth, itemHeight);
QQSquareCollectionViewFlowLayout *collectionViewFlowLayout = [[QQSquareCollectionViewFlowLayout alloc] initWithSectionInset:sectionInset interitemSpacing:interitemSpacing lineSpacing:lineSpacing itemSize:itemSize];
//设置布局的滚动方向
collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
_collectionView.backgroundColor = kQQViewBaseBackgroundColor;
_collectionView.dataSource = self;
_collectionView.delegate = self;
_collectionView.showsHorizontalScrollIndicator = NO;
}
return _collectionView;
}
网友评论