前言

最终效果:

android 瀑布流加载卡顿 ios瀑布流_数组

之前在很多的App上看到过瀑布流这种效果,而笔者在之前的开发中也没有遇到过使用这种效果的情况,大多数都是一些排列整齐的类似9宫格那样的平铺,因此对高度不一样的布局笔者还没有写过。今天笔者来带大家实现一下这种效果吧。

思路详解

咋一看这界面,我们可以用UITableView、UICollectionView,甚至你也可以UIScrollView自己撸一个,不过相信大多数人会选择UICollectionView来做。我们可以通过自定义UICollectionViewLayout来实现,这里笔者使用的是自定义UICollectionViewFlowLayout,从官方文档可以知道后者继承于前者。

自定义UICollectionViewLayout的关键两步是先后重载下面两个方法:

- (void)prepareLayout;

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;

所以我们思路是在- (void)prepareLayout;计算出所有item的frame,并赋值给当前item的UICollectionViewLayoutAttributes
接下来的问题就划归为设置每个item的frame,这里我们可以抽象出一个“列”的概念,除此之外我们还需要定义一个数组用于存储每一列的高度,因为我们在显示的时候,每一个item的都接在最短的那一列的下面。以此规则循环下去,直到所有的item都设置完毕。
最后我们通过- (CGSize)collectionViewContentSize
返回整个CollectionView的size。

细节描述

首先我们来解决每一个item的位置,也就是(x,y,w,h)。由效果图我们可以看出,每一个item的x,w和列的数量有关系,因此我们定义一个常量columCount用于记录列的个数。然后我们确定每个item的宽度(即w),宽度=整个屏幕宽度-(左边距)-(右边距)-(列数-1)*列间距,一般情况使用这种布局,后台返回的数据会有每一个item图片的宽和高,因此我们可以用这样一个比例得到我们item的高度。w/h=图片宽/图片高,所以item的

高度=图片高/图片宽 * w

我们声明一个数组用于记录最短列,声明一个变量记录最短列的高度,并且声明一个min变量记录最短列所在的索引。因此item的x=左边距+索引*(列间距+item宽度),y=最短列的高度
然后再更新最短的高度(最短高度=y+列间距+item的高度)。
到这里我们就确定好了每一个item的位置了,我们用一个数组装着这些item,用于- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;这个方法。
可是运行程序,我们会发现collectionView的高度并不是我们预期的,因此我们还要声明一个变量用于记录最高的item的高度。
最后写在- (CGSize)collectionViewContentSize
该方法里面。
至此我们的瀑布流就已经完成了。按照往常一下,代码上传了,代码中有详细解释,如果有需要,点击此处下载
如有更好的处理方式或者有任何疑问,欢迎联系!