类似购物平台商品展示的瀑布流效果,通过collectionView实现。需要自己自定义layout。
首先自己创建一个CaCollectionViewLayout 继承于UICollectionViewLayout
.h文件定义属性,方法等:
//总列数
@property (nonatomic, assign) NSInteger columnCount;
//列间距
@property (nonatomic, assign) NSInteger columnSpacing;
//行间距
@property (nonatomic, assign) NSInteger rowSpacing;
//section到collectionView的边距
@property (nonatomic, assign) UIEdgeInsets sectionInset;
//保存每一列最大y值的数组
@property (nonatomic, strong) NSMutableDictionary *maxYDic;
//保存每一个item的attributes的数组
@property (nonatomic, strong) NSMutableArray *attributesArray;
//计算item高度的block,将item的高度与indexPath传递给外界
@property (nonatomic,strong) CGFloat(^itemHeightBlock)(CGFloat itemHeight,NSIndexPath *indexPath);
//设置item间距
- (void)setColumnSpacing:(NSInteger)columnSpacing rowSpacing:(NSInteger)rowSepacing sectionInset:(UIEdgeInsets)sectionInset;
//初始化方法
- (instancetype)initWithColumnCount:(NSInteger)columnCount;
自定义layout需要实现四个方法:
- (void)prepareLayout;
-(CGSize)collectionViewContentSize;
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;
直接上代码:
- (void)prepareLayout {
//初始化字典,有几列就有几个键值对,key为列,value为列的最大y值,初始值为上内边距
for (int i = 0; i obj.floatValue) {
minIndex = key;
}
}];
//根据最短列的列数计算item的x值
CGFloat itemX = self.sectionInset.left + (self.columnSpacing + itemWidth) * minIndex.integerValue;
//item的y值 = 最短列的最大y值 + 行间距
CGFloat itemY = [self.maxYDic[minIndex] floatValue] + self.rowSpacing;
//设置attributes的frame
attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
//更新字典中的最大y值
self.maxYDic[minIndex] = @(CGRectGetMaxY(attributes.frame));
return attributes;
}
//返回rect范围内item的attributes
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
return self.attributesArray;
}
数组和字典记得初始化,此时自定义的布局已经完成。
接下来,我们需要自定义一个CollectionViewCell
重写init方法
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
//添加自己需要个子视图控件
return self;
}
然后就是使用的时候:
CaCollectionViewLayout *layout = [[CaCollectionViewLayout alloc]init];
[layout setColumnSpacing:10 rowSpacing:10 sectionInset:UIEdgeInsetsMake(10, 10, 20, 10)];
[layout setItemHeightBlock:^CGFloat(CGFloat itemHeight, NSIndexPath *indexPath) {
//根据图片的原始尺寸,及显示宽度,等比例缩放来计算显示高度
}];
self.collectionView = [[UICollectionView alloc]initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.backgroundColor = [UIColor whiteColor];
[self.collectionView registerClass:[myCell class] forCellWithReuseIdentifier:@"layoutCell"];
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.images.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
myCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"layoutCell" forIndexPath:indexPath];
//在这里对cell中的imageview设置图片 或者在自定义的cell中 重写set方法 设置图片都可以 推荐使用SDWebImage加载图片
return cell;
}
至此,一个简单的瀑布流效果已经完成。
具体可查看Demo