自定义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 ...
随机推荐
- 312. 戳气球【困难】【区间DP】
题目链接 有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.每当你戳破一个气球 i 时,你可以获得 nums[left] * ...
- dubbo视频分享
一.基础篇 第001节--课程介绍 第01节--使用Dubbo对传统工程进行服务化改造的思路介绍 第02节--使用Dubbo对传统工程进行服务化改造 第03节--ZooKeeper注册中心安装 第04 ...
- 快速创建vuepress项目(使用vuepress写文档)
vuepress的官方文档:https://vuepress.vuejs.org/zh/guide/ 参考:https://segmentfault.com/a/1190000016333850 ht ...
- vue组件的props
刚开始学习vue组件的时候经常被 props这个传值搞晕,做个笔记 Vue.component('item', { template: '#item-template', props: { model ...
- xml 单例类
MD5JSON.h #pragma once #include "include/json/json.h" #include "include/md5/md5.h&quo ...
- (转)H264--1--编码原理以及I帧B帧P帧 .
转:http://blog.csdn.net/yangzhongxuan/article/details/8003504 ---------------------- 前言 ------------- ...
- 阿里云CentOs7上安装JDK
一.查看服务器是否已经预装了JDK 在拿到新机器以后,要先看下机器上是否已经预装了JDK,命令: rpm -qa|grep jdk 如果有的话,卸载openjdk(无需输全称).命令: yum -y ...
- tomcat mysql 练习
[root@k8s-master tomcat_demo]# cat mysql-rc.yml apiVersion: v1 kind: ReplicationController metadata: ...
- flexbox属性速览及常见布局实现
CSS3 弹性盒子(Flex Box)弹性盒子是即 CSS2 浮动布局后, CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同 ...
- Spring 声明式事务管理(11)
案例分析 本案例是图书管理系统精简部分,在数据库中有3张表.分别保存图书库存.图书信息和用户信息.下面是建表SQL语句 1 DROP TABLE IF EXISTS store; 2 DROP TAB ...