前段时间, 做一个羡慕, 需要使用到瀑布流! 说道瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从scrollView 到 tableView 书写的瀑布流, 然后再到2012年iOS6 苹果API 新加进的collectionView进行的瀑布流封装! 确实, 不论是写起来还是用起来都要方便很多!

  由于项目开发中需要使用到很像瀑布流, 本来想着懒省事, 直接搜一个第三方, 可搜了一会, 并没有搜到有关横向瀑布流的第三方! 于是就决定自己写一个吧! 里边用到的就是UICollecitionViewFlowLayout 的一个UICollectionViewLayoutAttributes 这个属性!

  要明白瀑布流的原理, 写起来就会方便很多! 我下代码, 就是喜欢加多注释, 能够方便自己去找问题, 也能把当时的思路给记下来! 所以, 代码看起来, 好多绿色的中文注释, 或许对大神来说, 很弱! 但是, 能然自己读懂, 让大家读懂就够了!哈哈, 废话不多说! 直接上代码了! 思路还有实现步骤全在代码里!

  .h 生命中只需要传入一个 你所需要横向瀑布流的行数, 还有一个model类的数组, model类是你自己定义的, 里边有图片的宽高,就可以了!

  有什么疑问, 或者写的不对的地方, 希望提出来, 我虚心学习, 向大家探讨探讨

 //
// JF HorizontalWaterFlowLayout.h
// ArtWorld
//
// Created by laouhn on 15/10/29.
// Copyright © 2015年 Jesonliu. All rights reserved.
// #import <UIKit/UIKit.h> @interface JF_HorizontalWaterFlowLayout : UICollectionViewFlowLayout // 总行数
@property (nonatomic, assign) NSInteger rowCount;
// 商品数据数组
@property (nonatomic, strong) NSArray *modelList; @end
 //
// JF HorizontalWaterFlowLayout.m
// ArtWorld
//
// Created by laouhn on 15/10/29.
// Copyright © 2015年 Jesonliu. All rights reserved.
// #import "JF HorizontalWaterFlowLayout.h"
#import "ArtCollectionViewCellModel.h" @interface JF_HorizontalWaterFlowLayout ()
@property (nonatomic, assign) CGFloat remmenberW; // 所有item的属性的数组
@property (nonatomic, strong) NSArray *layoutAttributesArray; // 定义布局属性的数组, 用来存放布局item 的属性 @end @implementation JF_HorizontalWaterFlowLayout
/**
* 布局准备方法 当collectionView的布局发生变化时 会被调用
* 通常是做布局的准备工作 itemSize.....
* UICollectionView 的 contentSize 是根据 itemSize 动态计算出来的
*/ - (void)prepareLayout {
[super prepareLayout];
// 根据行数 计算item的高度 所有item 的高度是一样的
// 内容页的高度
CGFloat contenHeight = self.collectionView.bounds.size.height - self.sectionInset.top - self.sectionInset.bottom;
// 行与行之间的距离
CGFloat marginY = self.minimumLineSpacing;
// item 的高度
CGFloat itemHeight = (contenHeight - marginY * (self.rowCount - )) / self.rowCount;
// 计算布局属性
[self computeAttributesWithItemWith:itemHeight];
} /**
根据itemHeight 计算布局属性
*/
- (void)computeAttributesWithItemWith:(CGFloat)itemHeight {
// 定义一个行宽数组 记录每一行的总宽度
CGFloat rowWidth[self.rowCount];
// 定义一个记录每一行的总item个数数组
NSInteger rowItemCount[self.rowCount]; // 此处为C语言格式, 定义两个数组, 元素个数为self.rowCount, 数组类型为CGFloat 和 NSInteger // 初始化
for (int i = ; i < self.rowCount; i++) {
rowWidth[i] = self.sectionInset.left; // 行宽 要加上分区距离左边的距离 所以初始距离 只有分区距左边的距离
rowItemCount[i] = ; // 初始化时, 是每一行item 的个数为零, 清空数组元素内容
} // 遍历modelList 数组, 计算相关属性
NSInteger index = ; // 定义索引变量, 初始值为零 NSMutableArray *attributesArray = [NSMutableArray arrayWithCapacity:self.modelList.count]; // 定义一个可变存储布局属性的数组, 并开辟空间大小为self.modelList.count个空间 // 遍历self.modelList 数组, 得到model 类, 获取属性
for (ArtCollectionViewCellModel *model in self.modelList) { // 创建路径, 记录item 所在分区分区和位置
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:]; // 根据路径创建对应的布局属性
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; // 找出最短的行号
NSInteger row = [self shortestRow:rowWidth]; // 追加在最短行, 使记录每一行的总item个数数组中最短行对应的元素个数 +1
rowItemCount[row]++; // X值
CGFloat itemX = rowWidth[row]; // 最短行的总宽度 // Y值
CGFloat itemY = (itemHeight + self.minimumLineSpacing) * row + self.sectionInset.top; // 计算, 注意逻辑性 // 等比例缩放 计算item 的宽度
CGFloat itemW = ([model.worksWidth floatValue] / [model.worksHeight floatValue]) * itemHeight; // 显示宽 / 显示高 = 实际宽 / 实际高
// 赋给布局属性的frame
attributes.frame = CGRectMake(itemX, itemY, itemW, itemHeight); // 添加到布局属性的数组中
[attributesArray addObject:attributes]; // 使列宽增加, 增量为item 自身的宽度, 加上两个item 之间的最小距离
rowWidth[row] += itemW + self.minimumInteritemSpacing; // 是索引+1
index++;
} // 找出 最宽行的行号
NSInteger row = [self widthestRow:rowWidth]; self.remmenberW = rowWidth[row]; // 根据最宽行设置itemSize 使用总宽度的平均值
CGFloat itemW = (rowWidth[row] - self.minimumInteritemSpacing * rowItemCount[row]) / rowItemCount[row]; self.itemSize = CGSizeMake(itemW, itemHeight); // 给属性数组设置数值
self.layoutAttributesArray = attributesArray.copy; } // 找出rowWidth 数组中最短行号 追加数据的时候 追加在最短行中
- (NSInteger)shortestRow:(CGFloat *)rowWidth {
CGFloat max = CGFLOAT_MAX;
NSInteger row = ;
for (int i = ; i < self.rowCount; i++) {
if (rowWidth[i] < max) {
max = rowWidth[i];
row = i;
}
}
return row; // 返回最短的行
} // 找出rowWidth 数组中最宽的行号
- (NSInteger)widthestRow:(CGFloat *)rowWidth {
CGFloat min = ;
NSInteger row = ;
for (int i = ; i < self.rowCount; i++) {
if (rowWidth[i] > min) {
min = rowWidth[i];
row = i;
}
}
return row;
} /**
* 跟踪效果:当到达要显示的区域时 会计算所有显示item的属性
* 一旦计算完成 所有的属性会被缓存 不会再次计算
* @return 返回布局属性(UICollectionViewLayoutAttributes)数组
*/
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { // 直接返回计算好的布局属性数组
return self.layoutAttributesArray;
} // 重写此方法, 改变collectionView的contentSize
- (CGSize )collectionViewContentSize{
return CGSizeMake(self.remmenberW, self.collectionView.bounds.size.height);
} @end

iOS横向瀑布流的封装的更多相关文章

  1. ios开发瀑布流框架的封装

    一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...

  2. ios图片瀑布流代码

    ios瀑布流,实现简单的瀑布流视图布局,可以显示网络图片,下拉刷新,上拉加载更多. 下载:http://www.huiyi8.com/sc/9087.html

  3. ios开发瀑布流框架的应用

    一:瀑布流框架的应用:将封装好的瀑布流框架导入,遵守协议 二:代码: #import "HMShopsViewController.h" #import "HMShopC ...

  4. iOS基础 - 瀑布流

    一.瀑布流简介 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pint ...

  5. iOS - UICollectionView 瀑布流 添加表头视图的坑

    UICollectionView 瀑布流 添加表头视图的坑 首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView的表头只要设置tab ...

  6. iOS开发瀑布流的实现

    //自定义布局,继承于UICollectionViewLayout #import <UIKit/UIKit.h> @class WaterFlowLayout; @protocol  W ...

  7. 用label实现横向瀑布流的方法

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXcAAAKxCAIAAAAn+3udAAAKqWlDQ1BJQ0MgUHJvZmlsZQAASImVlg

  8. 飞流直下的精彩 -- 淘宝UWP中瀑布流列表的实现

    在淘宝UWP中,搜索结果列表是用户了解宝贝的重要一环,其中的图片效果对吸引用户点击搜索结果,查看宝贝详情有比较大的影响.为此手机淘宝特意在搜索结果列表上采用了2种表现方式:一种就是普通的列表模式,而另 ...

  9. iOS 瀑布流封装

    代码地址如下:http://www.demodashi.com/demo/12284.html 一.效果预览 功能描述:WSLWaterFlowLayout 是在继承于UICollectionView ...

随机推荐

  1. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. sublime text 主题推荐

    Soda Spacegray Flatland Tomorrow Base 16 Solarized Predawn itg.flat 其他所有的配色方案和主题.

  3. mrql初级教程-使用(er)

    最近使用mrql做xml文件解析,使用xpath来进行判断 使用的方法如下,其中t.mrql文件如下: v =args[1];store ty:=source(xml,args[0],{"p ...

  4. 现在都是python 单独开发框架 执行脚本,处理结果,发报告之类的

    现在都是python 单独开发框架 执行脚本,处理结果,发报告之类的

  5. oc js 交互

    http://blog.csdn.net/lwjok2007/article/details/47058101     iOS调JS http://blog.csdn.net/lwjok2007/ar ...

  6. 所有事件event集锦

    'mousedown touchstart', 'mousemove touchmove', 'mouseup mouseleave touchend touchleave touchcancel', ...

  7. [iOS Animation]-CALayer 显示方式

    寄宿图 图片胜过千言万语,界面抵得上千图片 ——Ben Shneiderman 我们在第一章『图层树』中介绍了CALayer类并创建了一个简单的有蓝色背景的图层.背景颜色还好啦,但是如果它仅仅是展现了 ...

  8. eclipse中安装配置maven

    1.首先说一下在windows中安装maven.非常简单... 到http://maven.apache.org/download.html中下载maven,截止笔者发文时,maven最新版本为mav ...

  9. mvc中怎么读取htm的文件

    @Html.Raw(File.ReadAllText(Server.MapPath("/Include/head01.htm")))

  10. 物理机(真实机)能ping通虚拟机,但是虚拟机无法ping通真实机(可能是防火墙问题)

    物理机IP地址:192.168.1.209 虚拟机IP地址:192.168.1.5.192.168.1.7.192.168.1.10 物理机设置: