前段时间, 做一个羡慕, 需要使用到瀑布流! 说道瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从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. ios开发证书,描述文件,bundle ID的关系

    苹果为了控制应用的开发与发布流程,制定了一套非常复杂的机制.这里面的关键词有:个人开发者账号,企业开发者账号,bundle ID,开发证书,发布证书(又叫"生产证书"),开发描述文 ...

  2. hbase 第一篇

    参考:http://www.jdon.com/38244 http://chuanwang66.iteye.com/blog/1683533

  3. sencha touch视频教程

    链接地址:http://v.youku.com/v_show/id_XOTI1MDg1ODQ4.html

  4. iOS平台软件开发工具(一)-新建的工程使用CocoaPods工具集成第三方框架

    CocoaPods是一款集合了上千个第三方开源库的开发工具,能够大幅度的提升团队项目的开发效率,降低时间成本. 那么就看一下CocoaPods这个工具在项目中的使用体现吧. 我们马上用ASIHTTPR ...

  5. 字典NSDictionary的常见用法

    // 动态获取字典的第一个典 NSString *firstKey = responseObject.keyEnumerator.nextObject;

  6. Góra urządzenia z dwoma zwiększyć moc może sprawić

    Zaprojektowany z rzeczywistym komfortu i łatwości od sportowca w swoim umyśle, kolejna edycja ze wzr ...

  7. javascript-函数及兼容

    1.事件绑定,删除,传播,默认方式,获取类型的兼容 var eventList = { //添加事件兼容 addEvent:function (event,type,backevent) { if ( ...

  8. 获取url参数和时间格式化

    1. 获取url参数: var url = request("url"); //获取url参数 function request(paras) { //decodeURI() 函数 ...

  9. WCF应用场景

    WCF全称Windows Communication Foundation,是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NET Framework 3.5的重要组成部分.使用 ...

  10. UIButton样式设置

    btn.frame = CGRectMake(x, y, width, height); [btn setTitle: @”search” forState: UIControlStateNormal ...