瀑布流

一、瀑布流设计方案

不可取.png

过于复杂.png

最优方案.png

二、瀑布流设计思路分析

1、自定义流水布局中,指定滚动方向、默认列数、行间距、列间距、以及指定cell的大小itemSize

2、可以提供一个数组columnMaxYs(记录当前每一列的最大Y值),假如3列,我们就提供一个3个元素的数组,记录所有布局属性

columnMaxYs实现懒加载,

2.并在prepareLayout方法中 :

1.先将columnMaxYs清空。

2.再进行初始化每个元素为0.

3.获取所有的Cell的布局属性,而每一个Cell的布局属性通过调用layoutAttributesForItemAtIndexPath:方式获取,而调用该方法,就会执行第4步

(至于为什么在prepareLayout方法中初始化,而不是在init方法初始化:是因为,该方法每次刷新都会调用,而init方法中只会在创建布局对象的时候只执行一次,例如:如果进行下拉刷新最新数据的时候,需求重新初始化数据,而如果我们使用的是init方法的话,并不会调用也就并不会清除之前的然后初始化,而使用该方法prepareLayout可以办到,因为它会再次调用,而init不会调用)

3.获取所有Cell的布局属性,

注意:对与所有Cell的布局属性,在第一次加载的时候需要计算一次,而当刷新collectionView的时候,当然也需要重新计算:所以我们提供一个布局属性的数组,来保存所有Cell的布局刷新,避免不必要的计算。 ——> 放在哪? 计算最好呢?  ———>  首选放在prepareLayout方法中,因为它会调用一次加载,而且当刷新的时候也会调用,满足需求,我们先将之前的全部移除,然后重新返回最新的布局属性数组; 但是,最好不要放在layoutAttributesForElementsInRect:方法(返回所有元素的布局属性数组中),因为改方法在滚动collectionView的时候,会频繁的调用,比较销毁性能。

3、在layoutAttributesForElementsInRect:方法(返回所有元素的布局属性数组 )

返回之前保存的所有Cell的布局属性数组

4、我们可以在layoutAttributesForItemAtIndexPath: 方法: 来调整 Cell的布局属性 , 指定Cell的 frame

1.在该方法中拿到当前cell的默认布局属性attrs,进行下面的调整,就可以实现瀑布流了2.遍历columnMaxYs数组,需要找出最短一列的 列号 与 最大Y值3. 确定当前Cell的 存放的x.y位置 以及widht与height      —> width:根据屏幕宽度与列数以及每列的宽度求出.  height:服务器返回的      —> x:需要根据当前最短一列的列号与Cell的宽度与间距可以求出来;y:可以根据当前最短一列的最大Y值 + 行间距可以求出4.重新设置修改当前Cell的布局属性attrs 的 frame即可。—> 之前已经拿到当前Cell的 默认布局属性,以及上一步已经获取到当前Cell需要存放的x.y位置后,5.将修改Cell布局属性之后的,当前列当前Cell的Y值最大,所有我们要将该值记录到数组columnMaxYs中,以便下次对比

5、注意:我们需要设置collectionView的contentSize,它才会滚动,那么我们如何设置呢?

——> 在定义布局类中,系统提供了一个collectionViewContentSize的get对象方法(决定collectionView的contentSize)                  —> contentSize的高度为:计算出最长那一列的最大Y值,也就是columnMaxYs的最大值 + 行间距

三、瀑布流的基本实现

效果图.png

1.创建一个控制器JPCollectionViewController,继承UICollectionViewController,使用我们自定义的流水布局JPWaterflowLayout(实现见其后)

#import"JPCollectionViewController.h"#import"JPWaterflowLayout.h"// 自定义流水布局@interfaceJPCollectionViewController()@end@implementationJPCollectionViewControllerstaticNSString*constreuseIdentifier =@"cellID";- (void)viewDidLoad {    [superviewDidLoad];// 切换布局self.collectionView.collectionViewLayout = [[JPWaterflowLayout alloc] init];}#pragma mark- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section {return30;}- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {UICollectionViewCell*cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];    cell.backgroundColor = [UIColororangeColor];returncell;}@end

2.自定义流水布局JPWaterflowLayout,继承UICollectionViewLayout

#import"JPWaterflowLayout.h"#define JPCollectionW self.collectionView.frame.size.width/** 每一行之间的间距 */staticconstCGFloatJPDefaultRowMargin =10;/** 每一列之间的间距 */staticconstCGFloatJPDefaultColumnMargin =10;/** 每一列之间的间距 top, left, bottom, right */staticconstUIEdgeInsetsJPDefaultInsets = {10,10,10,10};/** 默认的列数 */staticconstintJPDefaultColumsCount =3;@interfaceJPWaterflowLayout()/** 每一列的最大Y值 */@property(nonatomic,strong)NSMutableArray*columnMaxYs;/** 存放所有cell的布局属性 */@property(nonatomic,strong)NSMutableArray*attrsArray;@end@implementationJPWaterflowLayout#pragma mark - 懒加载- (NSMutableArray*)columnMaxYs{if(!_columnMaxYs) {        _columnMaxYs = [[NSMutableArrayalloc] init];    }return_columnMaxYs;}- (NSMutableArray*)attrsArray{if(!_attrsArray) {        _attrsArray = [[NSMutableArrayalloc] init];    }return_attrsArray;}#pragma mark - 实现内部的方法/**

* 决定了collectionView的contentSize

*/- (CGSize)collectionViewContentSize{// 找出最长那一列的最大Y值CGFloatdestMaxY = [self.columnMaxYs[0] doubleValue];for(NSUIntegeri =1; i

* 说明所有元素(比如cell、补充控件、装饰控件)的布局属性

*/- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{returnself.attrsArray;}/**

* 说明cell的布局属性

*/- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath{UICollectionViewLayoutAttributes*attrs = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];/** 计算indexPath位置cell的布局属性 */// 水平方向上的总间距CGFloatxMargin = JPDefaultInsets.left + JPDefaultInsets.right + (JPDefaultColumsCount -1) * JPDefaultColumnMargin;// cell的宽度CGFloatw = (JPCollectionW - xMargin) / JPDefaultColumsCount;// cell的高度,测试数据,随机数CGFloath =50+ arc4random_uniform(150);// 找出最短那一列的 列号 和 最大Y值CGFloatdestMaxY = [self.columnMaxYs[0] doubleValue];NSUIntegerdestColumn =0;for(NSUIntegeri =1; i columnMaxY) {            destMaxY = columnMaxY;            destColumn = i;        }    }// cell的x值CGFloatx = JPDefaultInsets.left + destColumn * (w + JPDefaultColumnMargin);// cell的y值CGFloaty = destMaxY + JPDefaultRowMargin;// cell的frameattrs.frame =CGRectMake(x, y, w, h);// 更新数组中的最大Y值self.columnMaxYs[destColumn] = @(CGRectGetMaxY(attrs.frame));returnattrs;}@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容