iOS 瀑布流的理解和封装
2016-10-27 16:48
176 查看
瀑布流的实现方法
第一种方法:在底部放一个scrollView,根据内容的大小定制view的大小,在scrollView上面进行排列,因为展示的内容太多,所以最好让view进行复用,这样的方法还是挺复杂的。第二种方法:在iOS6之后有了流布局之后,由系统帮你实现cell复用,工作就简单了很多。
今天主要说的就是第二种方法,实现瀑布流的思路及做简单的封装
因为瀑布流也是一种布局,所以我们不能去继承流布局本身的流水布局,因为那种布局每个格子的大小都是固定的。所以我们要继承UICollectionViewLayout。
我们需要实现的方法
- (void)prepareLayout每一次刷新对设置进行初始化,去清除之前计算的数据
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect返回每一个cell的属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath设置每一个cell对应的属性
- (CGSize)collectionViewContentSize返回内容的高度,内容的高度根据最后一行最长的一列计算
我们需要针对数据源的高去写cell的高,因为瀑布流是长短不一的,所以我们需要计算出每一行最短的那一列
下面贴出动态计算cell高度的代码吧
/** 返回indexPath位置cell对应的布局属性*/ - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { //先创建布局属性 UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; //cell宽度 = (collectionView的宽度 - 左边距 - 右边距 - (列数 - 1)* 列间距)/ 3 CGFloat width = (self.collectionView.frame.size.width - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount; //cell高度 = 传进来的高度 CGFloat height = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:width]; //如果是第一行 //y = 上边距 /** * 如果不是第一行,需要找出最短的一列 * 初始化的时候,用一个数组存储第一行的每个cell的maxY值 * 定义一个最短高度的变量,遍历cellmaxY值数组,让变量等于最短的那一个,得到最短的列 */ //最短的行号,默认第一列 NSInteger minColumnCount = 0; //最短的y值,默认第一列 CGFloat minColunmnMaxY = [self.columnHeights[0] floatValue]; for (NSInteger i = 1; i < self.columnCount; ++i) { //取出第i列高度 CGFloat columnHeight = [self.columnHeights[i] floatValue]; if (minColunmnMaxY > columnHeight) { minColunmnMaxY = columnHeight; minColumnCount = i; } } //x = 左边距 + 最短列位置 * (宽度 + 列间距) CGFloat x = self.edgeInsets.left + minColumnCount * (width + self.columnMargin); //有了最短的行,y = 最短列maxY值 + 列间距 CGFloat y = minColunmnMaxY; if (y != self.edgeInsets.top) { y += self.rowMargin; } //设置frame attributes.frame = CGRectMake(x, y, width, height); //更新高度 self.columnHeights[minColumnCount] = @(CGRectGetMaxY(attributes.frame)); // 记录内容的高度 CGFloat columnHeight = [self.columnHeights[minColumnCount] floatValue]; if (self.contentHeight < columnHeight) { self.contentHeight = columnHeight; } return attributes; }
这里已经计算出了最短的列和最长的列,所以每一个cell该怎么放,以及整个UICollectionView的内容大小也已经计算出来
今天就到这里吧,感觉写的也不太满意,哪里有问题可以指出来。
相关文章推荐
- ios开发瀑布流框架的封装
- IOS电子书、启动页集成、瀑布流封装、地图应用、自定义tabBar等源码
- iOS 第三课 九宫格建立 封装以及mvc的初步理解
- iOS 瀑布流封装
- IOS电子书、启动页集成、瀑布流封装、地图应用、自定义tabBar等源码
- iOS学习笔记--瀑布流封装
- 对面向对象封装概念的理解
- ios封装静态库技巧两则
- 关于ios phone APP生命周期的一点理解
- 理解iOS中的MVC设计模式
- IOS 学习笔记(四)ios理解
- 我理解的封装继承和多态
- 对面象对象封装的一点理解
- IOS开发中委托代理(degegate)的理解和使用示例
- ios的一个架构小例子---异步请求的封装
- [iOS开发高效第三方库之]sqlite3封装库---FMDB
- 封装的理解
- 由VCL中的代码理解VCL中的消息处理机制(Delphi对消息机的封装)
- ado.net调用存储过程的一个封装类(网上找的不怕只怕自己不去理解)
- 我理解的封装继承和多态