iOS横向瀑布流的封装
前段时间, 做一个羡慕, 需要使用到瀑布流! 说道瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从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横向瀑布流的封装的更多相关文章
- ios开发瀑布流框架的封装
一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...
- ios图片瀑布流代码
ios瀑布流,实现简单的瀑布流视图布局,可以显示网络图片,下拉刷新,上拉加载更多. 下载:http://www.huiyi8.com/sc/9087.html
- ios开发瀑布流框架的应用
一:瀑布流框架的应用:将封装好的瀑布流框架导入,遵守协议 二:代码: #import "HMShopsViewController.h" #import "HMShopC ...
- iOS基础 - 瀑布流
一.瀑布流简介 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pint ...
- iOS - UICollectionView 瀑布流 添加表头视图的坑
UICollectionView 瀑布流 添加表头视图的坑 首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView的表头只要设置tab ...
- iOS开发瀑布流的实现
//自定义布局,继承于UICollectionViewLayout #import <UIKit/UIKit.h> @class WaterFlowLayout; @protocol W ...
- 用label实现横向瀑布流的方法
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXcAAAKxCAIAAAAn+3udAAAKqWlDQ1BJQ0MgUHJvZmlsZQAASImVlg
- 飞流直下的精彩 -- 淘宝UWP中瀑布流列表的实现
在淘宝UWP中,搜索结果列表是用户了解宝贝的重要一环,其中的图片效果对吸引用户点击搜索结果,查看宝贝详情有比较大的影响.为此手机淘宝特意在搜索结果列表上采用了2种表现方式:一种就是普通的列表模式,而另 ...
- iOS 瀑布流封装
代码地址如下:http://www.demodashi.com/demo/12284.html 一.效果预览 功能描述:WSLWaterFlowLayout 是在继承于UICollectionView ...
随机推荐
- Clustering text documents using k-means
源代码的链接为http://scikit-learn.org/stable/auto_examples/text/document_clustering.html Loading 20 newsgro ...
- iOS WebView的用法
一.UIWebView 可以加载和显示某个URL的网页,也可以显示基于HTML的本地网页或部分网页: a. 加载 URL WebView = [[UIWebView alloc] initWithFr ...
- Ubuntu和win10双系统Grup无法引导解决方案
通常我们经常安装双系统, 但是有时候安装完系统无法正常引导, 以下就说明Ubuntu和win10双系统, win10在grub界面不断循环的解决方案 直接在win10启动项目上按e进入编辑模式 在文档 ...
- PHP和MySQL Web开发(原书第4版) 高清PDF+源代码
PHP和MySQL Web开发(原书第4版) 高清PDF+源代码 [日期:2014-08-06] 来源:Linux社区 作者:Linux [字体:大 中 小] 内容简介 <PHP和My ...
- Linux中cat、more、less、tail、head命令的区别
一.cat 显示文件连接文件内容的工具 cat 是一个文本文件(查看)和(连接)工具,通常与more搭配使用,与more不同的是cat可以合并文件.查看一个文件的内容,用cat比较简单,就是cat后面 ...
- iOS8学习笔记2--autolayout
iOS支持的设备如今已经具有了很多的尺寸,针对这些不同的尺寸每一个都做一个独立的APP肯定是不现实的,于是苹果在iOS8之后推出了autolayout和sizeclass,同时还有VFL界面设计语言 ...
- 防止多个UIAlertView重叠弹出
http://www.jianshu.com/p/7ac398ef4532 项目中可能会遇到这种情况,好几个alertView因为逻辑关系全部弹出,用户需要一个个的点击才能将所有的alertView取 ...
- ubuntu apache2 ssl配置
Ubuntu下HTTPS配置非常简单,对大部分用户而言,使用普通的自签名证书,只需按照步骤进行就可以了,无需了解密钥.证书的更多知识,更深的背景 知识还有RSA算法.DES算法.X509规范.CA机构 ...
- IOS9提示“不受信任的开发者”如何处理
iPhone升级到IOS9版本后,发现部分APP在下载后首次运行时,都会提示“不受信任的应用程序开发者”,这是因为企业证书发布的APP,没有经过AppStore审核,于是iOS对用户做出一个安全性的提 ...
- libusb 开发者指南-牛胜超(转)
源:libusb 开发者指南 libusb Developers Guidelibusb 开发者指南 原作者:Johannes Erdfelt翻译者:牛胜超 Table of Contents目录 P ...