自定义UICollectionViewLayout(适用于多个section)
一、自定义layout主要方法
重写系统的- (void)prepareLayout 方法;
其实就是计算每个cell的frame和其它相关属性。

二、在网上看了好多自定义的layout 但是没有多section的,就整了这个……
全部代码:
@class ForeverGuardFlowLayout;
@protocol ForeverGuardFlowLayoutDelegate <NSObject>
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(ForeverGuardFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
@end @interface ForeverGuardFlowLayout : UICollectionViewFlowLayout @property(nonatomic, assign)NSUInteger numberOfColumn;//列数
@property(nonatomic, assign)id<ForeverGuardFlowLayoutDelegate>delegate; @end
@interface ForeverGuardFlowLayout()
//存放每一列的高度
@property (nonatomic, retain) NSMutableArray *columnHeightsArray; //每个section的每一列的高度
@property (nonatomic, retain) NSMutableArray *collectionHeightsArray; //存放每一个cell的属性
@property (nonatomic, retain) NSMutableArray *attributesArray; @end
@implementation ForeverGuardFlowLayout /**
每个区的最小高度 @param section 区索引
@return 高度
*/
- (CGFloat)minHeightWithSection:(NSInteger)section{
CGFloat min = ;
for (NSNumber *height in _collectionHeightsArray[section]) {
if (min > [height floatValue]) {
min = [height floatValue];
}
}
return min;
} /**
每个区的初始Y坐标 @param section 区索引
@return Y坐标
*/
- (CGFloat)maxHeightWithSection:(NSInteger)section{ if (section>) {
CGFloat max = ;
for (int i=; i<section; i++) {
max += [self maxHeightAboutSection:_collectionHeightsArray[i]];
}
return max;
}else{
return ;
} } /**
每个区的最大高度 @param dataArr 每个区的所有列的高度
@return 最大高度
*/
- (CGFloat)maxHeightAboutSection:(NSMutableArray *)dataArr{
CGFloat max = ;
for (NSNumber *heigth in dataArr) {
if (max < [heigth floatValue]) {
max = [heigth floatValue];
}
}
return max; } /**
collectionView的显示高度
*/
- (CGFloat)collectionHeight{
CGFloat max = ;
for (NSMutableArray *sectionArr in _collectionHeightsArray) {
max += [self maxHeightAboutSection:sectionArr];
}
return max;
} /**
当前区的最小高度的索引 @param section 当前区
@return 最小高度的索引
*/
- (NSUInteger)indexOfMinHeightWithSection:(NSInteger)section{
NSUInteger index = ;
NSMutableArray *sectionArr = _collectionHeightsArray[section];
for (int i=; i<sectionArr.count; i++) {
CGFloat height = [sectionArr[i] floatValue];
if (height == [self minHeightWithSection:section]) {
index = i;
return index;
}
}
return index;
} /**
重写系统prepareLayout方法 (设置item的坐标等属性)
*/
- (void)prepareLayout{
[super prepareLayout]; _attributesArray = [[NSMutableArray alloc] init]; _columnHeightsArray = [NSMutableArray arrayWithCapacity:self.numberOfColumn]; NSUInteger sectionCount = [self.collectionView numberOfSections];
_collectionHeightsArray = [NSMutableArray arrayWithCapacity:sectionCount]; for (int index = ; index<sectionCount; index++) {
NSMutableArray *columnArr = [NSMutableArray array];
for (int i=; i<self.numberOfColumn; i++) {
[columnArr addObject:@0.0];
}
[_collectionHeightsArray addObject:columnArr];
} CGFloat totalWidth = self.collectionView.frame.size.width; CGFloat x = ;
CGFloat y = ; for (int index= ; index<sectionCount; index++) {
NSUInteger itemCount = [self.collectionView numberOfItemsInSection:index];
x = ;
y = [self maxHeightWithSection:index];
for (int i=; i<itemCount; i++) {
NSUInteger numberIfSoace = self.numberOfColumn-;
CGFloat spaceWidth = 7.5;//item左右间距
CGFloat width = (totalWidth - spaceWidth*numberIfSoace)/self.numberOfColumn; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:index]; CGSize imageSize =[self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath]; CGFloat height = width * imageSize.height / imageSize.width; UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; attributes.frame = CGRectMake(x, y, width, height);
[_attributesArray addObject:attributes]; NSUInteger minHeightIndex = [self indexOfMinHeightWithSection:index]; CGFloat minHeight = [_collectionHeightsArray[index][minHeightIndex] floatValue];
CGFloat lineHeight = 7.5;//item上下间距 _collectionHeightsArray[index][minHeightIndex] = [NSNumber numberWithFloat:minHeight+lineHeight+height];
minHeightIndex = [self indexOfMinHeightWithSection:index]; x = (spaceWidth + width) * minHeightIndex; y += [self minHeightWithSection:index]; } } } /**
返回collectionView的界面显示大小
*/
- (CGSize)collectionViewContentSize{
return CGSizeMake(self.collectionView.frame.size.width, [self collectionHeight]);
} /**
将所有的layoutAttributes重写布局
*/
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
return _attributesArray;
}
@end
.m文件
@interface ForeverGuardFlowLayout()
//存放每一列的高度
@property (nonatomic, retain) NSMutableArray *columnHeightsArray;
//每个section的每一列的高度
@property (nonatomic, retain) NSMutableArray *collectionHeightsArray;
//存放每一个cell的属性
@property (nonatomic, retain) NSMutableArray *attributesArray; @end
@implementation ForeverGuardFlowLayout /**
每个区的最小高度 @param section 区索引
@return 高度
*/
- (CGFloat)minHeightWithSection:(NSInteger)section{
CGFloat min = ;
for (NSNumber *height in _collectionHeightsArray[section]) {
if (min > [height floatValue]) {
min = [height floatValue];
}
}
return min;
} /**
每个区的初始Y坐标 @param section 区索引
@return Y坐标
*/
- (CGFloat)maxHeightWithSection:(NSInteger)section{ if (section>) {
CGFloat max = ;
for (int i=; i<section; i++) {
max += [self maxHeightAboutSection:_collectionHeightsArray[i]];
}
return max;
}else{
return ;
} } /**
每个区的最大高度 @param dataArr 每个区的所有列的高度
@return 最大高度
*/
- (CGFloat)maxHeightAboutSection:(NSMutableArray *)dataArr{
CGFloat max = ;
for (NSNumber *heigth in dataArr) {
if (max < [heigth floatValue]) {
max = [heigth floatValue];
}
}
return max; } /**
collectionView的显示高度
*/
- (CGFloat)collectionHeight{
CGFloat max = ;
for (NSMutableArray *sectionArr in _collectionHeightsArray) {
max += [self maxHeightAboutSection:sectionArr];
}
return max;
} /**
当前区的最小高度的索引 @param section 当前区
@return 最小高度的索引
*/
- (NSUInteger)indexOfMinHeightWithSection:(NSInteger)section{
NSUInteger index = ;
NSMutableArray *sectionArr = _collectionHeightsArray[section];
for (int i=; i<sectionArr.count; i++) {
CGFloat height = [sectionArr[i] floatValue];
if (height == [self minHeightWithSection:section]) {
index = i;
return index;
}
}
return index;
} /**
重写系统prepareLayout方法 (设置item的坐标等属性)
*/
- (void)prepareLayout{
[super prepareLayout];
_attributesArray = [[NSMutableArray alloc] init];
_columnHeightsArray = [NSMutableArray arrayWithCapacity:self.numberOfColumn];
NSUInteger sectionCount = [self.collectionView numberOfSections];
_collectionHeightsArray = [NSMutableArray arrayWithCapacity:sectionCount];
for (int index = ; index<sectionCount; index++) {
NSMutableArray *columnArr = [NSMutableArray array];
for (int i=; i<self.numberOfColumn; i++) {
[columnArr addObject:@0.0];
}
[_collectionHeightsArray addObject:columnArr];
}
CGFloat totalWidth = self.collectionView.frame.size.width; CGFloat x = ;
CGFloat y = ; for (int index= ; index<sectionCount; index++) {
NSUInteger itemCount = [self.collectionView numberOfItemsInSection:index];
x = ;
y = [self maxHeightWithSection:index];
for (int i=; i<itemCount; i++) {
NSUInteger numberIfSoace = self.numberOfColumn-;
CGFloat spaceWidth = 7.5;//item左右间距
CGFloat width = (totalWidth - spaceWidth*numberIfSoace)/self.numberOfColumn;
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:index];
CGSize imageSize =[self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
CGFloat height = width * imageSize.height / imageSize.width;
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attributes.frame = CGRectMake(x, y, width, height);
[_attributesArray addObject:attributes]; NSUInteger minHeightIndex = [self indexOfMinHeightWithSection:index];
CGFloat minHeight = [_collectionHeightsArray[index][minHeightIndex] floatValue];
CGFloat lineHeight = 7.5;//item上下间距 _collectionHeightsArray[index][minHeightIndex] = [NSNumber numberWithFloat:minHeight+lineHeight+height];
minHeightIndex = [self indexOfMinHeightWithSection:index]; x = (spaceWidth + width) * minHeightIndex;
y = [self minHeightWithSection:index]+[self maxHeightWithSection:index];
}
}
} /**
返回collectionView的界面显示大小
*/
- (CGSize)collectionViewContentSize{
return CGSizeMake(self.collectionView.frame.size.width, [self collectionHeight]);
} /**
将所有的layoutAttributes重写布局
*/
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
return _attributesArray;
}
@end
自定义UICollectionViewLayout(适用于多个section)的更多相关文章
- 自定义UICollectionViewLayout 实现瀑布流
今天研究了一下自定义UICollectionViewLayout. 看了看官方文档,要自定义UICollectionViewLayout,需要创建一个UICollectionViewLayout的子类 ...
- 自定义UICollectionViewLayout之CATransform3D
1.自定义UICollectionViewLayout旋转效果 之前有自定义UICollectionViewLayout(适用于多个section),本文是一个对cell进行CATransform3D ...
- 自定义UICollectionViewLayout并添加UIDynamic - scorpiozj(转)
转载自:http://www.tuicool.com/articles/jM77Vf 自定义UICollectionViewLayout并添加UIDynamic UICollectionVie ...
- 自定义UICollectionViewLayout并添加UIDynamic
大家也可以到这里查看. UICollectionView是iOS6引入的控件,而UIDynamicAnimator是iOS7上新添加的框架.本文主要涵盖3部分: 一是简单概括UICollectionV ...
- iOS 关于自定义UICollectionViewLayout实现复杂布局
UICollectionView的简单介绍 UICollectionView的结构 Cells Supplementary Views 追加视图 (类似Header或者Footer) Decorati ...
- 自定义UICollectionViewLayout 布局实现瀑布流
自定义 UICollectionViewLayout 布局,实现瀑布流:UICollectionView和UICollectionViewCell 另行创建,这只是布局文件, 外界控制器只要遵守协议并 ...
- 自定义UICollectionViewLayout之瀑布流
目标效果 因为系统给我们提供的 UICollectionViewFlowLayout 布局类不能实现瀑布流的效果,如果我们想实现 瀑布流 的效果,需要自定义一个 UICollectionViewLay ...
- iOS自定义UICollectionViewLayout之瀑布流
目标效果 因为系统给我们提供的 UICollectionViewFlowLayout 布局类不能实现瀑布流的效果,如果我们想实现 瀑布流 的效果,需要自定义一个 UICollectionViewLay ...
- 自定义UICollectionViewLayout
UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一颗新星.它和UITableView共享API设计,但也在UITableView上做了一些扩展.UICollectio ...
随机推荐
- 8分钟带你深入浅出搞懂Nginx
Nginx是一款轻量级的Web服务器.反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用. 图基本上说明了当下流行的技术架构,其中Nginx有点入口网关的味道. 反向代 ...
- 天道神诀---DHCP服务(上篇)
DHCP DHCP(Dynamic Host Configuration Protocol, 动态主机配置协议),被应用在局域网环境中,主要作用是集中的管理.分配IP地址,使网路环境中的主机动态的获得 ...
- 【洛谷】P1009阶乘之和
题目链接:https://www.luogu.org/problemnew/show/P1009 题意:给一个整数n(n<50),求$ \sum^{n}_{i=1} i! $ 题解:我..拿py ...
- Linux网络配置 RPM命令 samba服务 Linux目录结构
第一种方法: (1)用root身份登录,运行setup命令进入到 text mode setup utiliy对网络进行配置,这里可以进行ip,子网掩码,默认网关,dns的设置.(2)这时网卡的配置没 ...
- 23种常用设计模式的UML类图
23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...
- MongoDB + Spark结合使用方案
MongoDB上海的活动已经结束快1个月了,我们再来回顾一下TJ在大会上进行的精彩分享吧~ MongoDB + Spark: 完整的大数据计算解决方案. Spark介绍 按照官方的定义,Spark 是 ...
- [笔记]Laravel TDD 胡乱记录
TDD: 测试驱动开发(Test-Driven Development),TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码. -- 载自TDD百度百科 参考 ...
- 校园商铺-2Logback配置与使用-3验证配置
1. 验证logback配置 1.1. 启动tomcat,得到CATALINA_BASE地址: 1.2 访问接口,查看日志 浏览器打开http://localhost:18080/o2o/supera ...
- 深入解读阿里云数据库POLARDB核心功能会话读一致性
POLARDB架构 我们知道,POLARDB是一个由多个节点构成的数据库集群,一个主节点,多个读节点.对外默认提供两个地址,一个是集群地址,一个是主地址,推荐使用集群地址,因为它具备读写分离功能可以把 ...
- 0919CSP-S模拟测试赛后总结
60分-rank36,不出所料又炸了. 总是试图稳住成绩,但就是不能避免这样的大起伏.这样不行啊. T1可是道sb题啊……对着题干yy了一个多小时,正解基本都想到了,只差一个结构体排序. 然而即使我真 ...