iosios10 collectionvieww怎么自定义区头

IOS封装自定义布局的方法
作者:世俗孤岛
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了IOS封装自定义布局的方法,需要的朋友可以参考下
1、对于经常使用的控件或类,通常将其分装为一个单独的类来供外界使用,以此达到事半功倍的效果
2、由于分装的类不依赖于其他的类,所以若要使用该类,可直接将该类拖进项目文件即可
3、在进行分装的时候,通常需要用到代理设计模式
二、代理设计模式
1、代理设计模式的组成
客户类(通常作为代理):通常委托这是角色来完成业务逻辑
真实角色:将客户类的业务逻辑转化为方法列表,即代理协议
代理协议:
定义了需要实现的业务逻辑
定义了一组方法列表,包括必须实现的方法或选择实现的方法
代理协议是代理对象所要遵循一组规则
若要作为代理,需要遵守代理协议,并且实现必须实现的代理方法
代理角色可以通过调用代理协议中的方法完成业务逻辑,也可以附加自己的操作
文字描述通常是抽象的,一下通过图示来阐述代理设计模式
三、自定义布局类的封装
1、业务逻辑
2、布局每个cell的业务逻辑
由于设置每个cell的布局属性的业务逻辑较复杂,特附上如下思维导图
3、封装思路封装需要根据客户类业务逻辑需求来提供接口
1)、通过代理协议的可选实现的方法获取的属性值的属性,需要设置默认值
2)、未提供默认值的且必须使用的属性,需要通过必须实现的方法来获得
3)、自定义布局提供的接口可选
列之间的间距
行之间的间距
4)、自定义布局提供的接口必选
每个元素的高度,宽度可以通过列数和列间距计算得到
四、封装步骤
设置代理协议,提供接口
//声明LYPWaterFlowLayout为一个类
@class LYPWaterFlowL
@protocol LYPWaterFlowLayoutDelegate &NSObject&
//必须实现的方法
/**获取瀑布流每个元素的高度*/
- (CGFloat)waterFlowLayout:(LYPWaterFlowLayout *)waterFlowLayout heightForItemAtIndex:(NSInteger)index itemWith:(CGFloat)itemW
//可选实现的方法
/**获取瀑布流的列数*/
- (NSInteger)columnCountInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowL
/**获取瀑布流列间距*/
- (CGFloat)columnMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowL
/**获取瀑布流的行间距*/
- (CGFloat)rowMarginInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowL
/**获取瀑布流的内边距*/
- (UIEdgeInsets)edgeInsetsInWaterFlowLayout:(LYPWaterFlowLayout *)waterFlowL
设置代理属性
@interface LYPWaterFlowLayout : UICollectionViewLayout
@property (nonatomic, weak) id&LYPWaterFlowLayoutDelegate&
设置通过可选代理方法获取属性值的属性的默认值
/**默认的列数*/
static const NSInteger LYPDefaultColumnCount = 3;
/**默认每一列之间的间距*/
static const CGFloat LYPDefaultColumMargin = 10;
/**默认每一行之间的间距*/
static const CGFloat LYPDefaultRowMargin = 10;
/**默认边缘间距*/
static const UIEdgeInsets LYPDefaultEdgeInsets = {10, 10, 10, 10};
设置通过可选代理方法获取属性值的属性的访问方式若代理提供属性值,则忽略默认值
- (NSInteger)columnCount
//判断代理是否实现了获取列数的可选方法
if ([self.delegate respondsToSelector:@selector(columnCountInWaterFlowLayout:)])
//实现,返回通过代理设置的列数
return [self.delegate columnCountInWaterFlowLayout:self];
//为实现,返回默认的列数
return LYPDefaultColumnC
注:其他属性值的获取与上述方法几乎完全相同,不再赘述
1)、设置需要的成员属性
/**所有cell的布局属性*/
@property (nonatomic, strong) NSMutableArray *attrsA
/**所有列的当前高度*/
@property (nonatomic, strong) NSMutableArray *columnH
2)、通过懒加载的方式初始化成员属性
/**--attrsArray--懒加载*/
- (NSMutableArray *)attrsArray
if (_attrsArray == nil)
_attrsArray = [NSMutableArray array];
return _attrsA
/**--columnHeights--懒加载*/
- (NSMutableArray *)columnHeights
if (_columnHeights == nil)
_columnHeights = [NSMutableArray array];
return _columnH
3)、初始化布局
- (void)prepareLayout
[super prepareLayout];
/**清除之前跟布局相关的所有属性,重新设置新的布局*/
//清除之前计算的所有列的高度
[self.columnHeights removeAllObjects];
//设置所有列的初始高度
for (NSInteger i = 0; i&self.columnC i++)
self.columnHeights[i] = @(self.edgeInsets.top);
//清除之前所有的布局属性
[self.attrsArray removeAllObjects];
/**开始创建每一个cell对应的布局属性*/
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (NSInteger i = 0; i& i++)
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
//获取indexPath位置cell对应的布局属性
UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
//将indexPath位置的cell的布局属性添加到所有cell的布局属性数组中
[self.attrsArray addObject:attrs];
4)、返回包含所有cell的布局属性的数组
- (nullable NSArray&UICollectionViewLayoutAttributes *& *)layoutAttributesForElementsInRect:(CGRect)rect
return self.attrsA
设置每一个cell的布局属性
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
//获取indexPath位置的布局属性
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
/**设置cell布局属性的frame*/
/***确定cell的尺寸***/
//获取collectionView的宽度
CGFloat collectionViewWidth = self.collectionView.frame.size.
//cell宽度
CGFloat width = ((collectionViewWidth - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columMargin)) / self.columnC
//cell高度
CGFloat height = [self.delegate waterFlowLayout:self heightForItemAtIndex:indexPath.item itemWith:width];
/***设置cell的位置***/
NSInteger destColumn = 0;
CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i&self.columnC i++)
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (minColumnHeight & columnHeight)
minColumnHeight = columnH
destColumn =
//计算cell的位置
CGFloat x = self.edgeInsets.left + destColumn * (width + self.columMargin);
CGFloat y = minColumnH
//判断是不是第一行
if (y != self.edgeInsets.top)
//若不是第一行,需要加上行间距
y += self.rowM
/**给cell的布局属性的frame赋值*/
attrs.frame = CGRectMake(x, y, width, height);
//更新最短那列的高度
self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
/**返回indexPath位置的cell的布局属性*/
5)、设置collectionView内容的尺寸
- (CGSize)collectionViewContentSize
//获取最高的那一列的高度
CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i&self.columnC i++)
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (maxColumnHeight & columnHeight)
maxColumnHeight = columnH
//返回collectionView的contentSize,高度为最高的高度加上一个行间距
return CGSizeMake(0, maxColumnHeight + self.rowMargin);
以上就是本文的全部内容,希望对大家的学习有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具> collectionView自定义layout
有时候可能需要不同的布局,Apple也提供了方便的布局间切换的方法。直接更改collectionView
一个CollectionView控件中,两个cell之间的间距如何设置?这是一个很常见的问题。当我们在网
GSKStretchyHeaderView,CHTCollectionViewWaterfallLayout ,JZNavigationExtension,其中第一个是给CollectionView添
我在前一篇博客中《iOS开发实战&&CollectionView点击事件与键盘隐藏结合案例》详细
本篇博客应该算的上CollectionView的高级应用了,从iOS开发之窥探UICollectionViewController(一)到今
良品铺子定义新零售:核心是数字化运营+极致体验。新零售如火如荼,不同的行业和企业
体验VultrVPS自定义ISO安装Windows完整过程,我们有些项目是需要在可视化Windows桌面或者VNC远
Android自定义控件水波加速球。
今天写的是Android中常用的自定义标题栏。
js容易被忽略的内容(一):JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“
Butter Knife Field and method binding for Android views。JakeWharton butterknife[1]是一个支持Android开发通过
大数据系列修炼Scala课程71:1、Scala界面Panel、Layout相关用法操作代码实战。
对UGUI的GridLayoutGroup组件进行拓展:最在在工作过程经常会使用到Grid Layout Group 组件,在使
4种必须知道的Android屏幕自适应解决方案,以下是Demo首页的预览图。
可能有的朋友在刚开始进行android开发的时候会遇到这样的问题,XML文件中的效果看不出来
MJRefresh - 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能。
猫猫分享,必须精品
原创文章,欢迎转载。转载请注明:翟乃玉的博客
地址:http:
不多说,好不好先看效果,之前做过一个scrollView的轮播图,但是很局限,很多多
该篇博客是在《iOS高级开发&&CollectionView的动态增删cell及模型重构》的基础上继续
在我刚初学iOS的时候,我就问一些大神,iOS开发中最难的哪些部分。有些人就说是自定义控
浅谈JDBC:jdbc是sun公司定义的一套访问数据库的规范,是java数据库连接。主要放在java sql和j
字符设备驱动:字符驱动模块程序,模块所需的大量符号和函数定义。
k-均值:一种基于型心的技术:k-均值算法把簇的型心定义为簇内点的均值。它的处理流 程
自定义WaveProgressView满足你所有水波纹加载需求。
Android基础系列 - 手势(二)自定义,识别手势。
简单介绍:说明: ($ fn layout)布局,依赖panel和resizable,默认分为5个区东east,西west,南south,北north,
如果同时设置android:layout_height=
"match_parent
" 和 android:layout_marginTop,会怎么样?
在layout_width设置为match_parent的时候,layout_weight所代表的是你的控件要优先尽可能的大,但这
线性布局linear_layout
HTML Boostrap-layout。
热门文章热门标签
12月10日 |
12月10日 |
12月10日 |
12月10日 |
12月10日 |
12月10日 |
12月10日 |
12月10日 |CollectionView瀑布流添加头视图,自定义Cell计算高度 - CSDN博客
CollectionView瀑布流添加头视图,自定义Cell计算高度
在开发时,看到CollectionView制作的瀑布流图册很好看,于是就做了一个,效果确实可以。刚好在开发时有这种布局需求,于是把之前做的瀑布流拿来改进,还是遇到了许多问题。
先看一下效果,
首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView只要设置
tableview.tableHeaderView就可以了,而collectionView需要在代理中设置头,尾视图。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString
*)kind atIndexPath:(NSIndexPath *)indexPath
& & UICollectionReusableView *reusableView =nil;
& & if (kind ==UICollectionElementKindSectionHeader) {
& & & & UICollectionReusableView *header = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@&HeaderView&forIndexPath:indexPath];
& & & & reusableView =
& & reusableView.backgroundColor = [UIColorgreenColor];
& & if (kind ==UICollectionElementKindSectionFooter)
& & & & UICollectionReusableView *footerview = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooterwithReuseIdentifier:@&FooterView&forIndexPath:indexPath];
& & & & footerview.backgroundColor = [UIColorpurpleColor];
& & & & reusableView =
& & return reusableV
但是你会发现,使用瀑布流的时候,UICollectionViewFlowLayout是自定义的布局,collectionView的代理不会走,在网上搜了很多也没有什么解决方法,都是一个版本的复制粘贴使用这种代理方法来设置的,因为他们没用使用自定义的瀑布流布局,Cell都是相同大小的布局,所以,这里就比较坑了。
最后在CocoChina的一个论坛搜到一个说加HeaderView的,看了一下,就是在自定义的Layout中添加加一个 Header类型的&UICollectionViewLayoutAttributes就可以。然后我把瀑布流的Cell的起始位置从headerView的最大Y开始布局。这样设置之后,controllerView中的代理方法才会走,要记得注册头视图哦,不然会崩。
然后还有一个问题就是,瀑布流自定义布局,这个网上很多,不懂的自己搜,我也是照网上的做,一开始内容都是图片,只要在自定义的Layout中根据当前cell的图片设置该cell的布局大小就行。方法也是先走的layout中的设置方法,再走CollectionView的代理方法,所以这里就比较坑了,要先把每个cell的大小根据内容计算出来给layout布局设置,再去代理方法中设置自定义的Cell的内容。一开始内容是一张图片还好,只要每次取出来计算image.size就可以了,而需求是自定义的cell中有图片,文字的一些内容,所以只能专门写一个计算cell宽高的类。网上有人写了个缓存这个宽高值的类,我就没有去做了。我贴一下关键的代码吧。
自定义的瀑布流布局Layout中,添加头和cell的Attribute,
- (void)prepareLayout
& & [superprepareLayout];
& & CGFloat screenW =CGRectGetWidth([UIScreenmainScreen].bounds);
重置每一列的最大Y值
& & [self.columnMaxYArrayremoveAllObjects];
& & for (int i =0; i &
self.columnCount; i ++) {
& & & & [self.columnMaxYArrayaddObject:@(self.sectionEdge.top)];
& & //计算所有cell的布局属性
& & [self.attributeArrayremoveAllObjects];
& & //头部视图
& & UICollectionViewLayoutAttributes * layoutHeader = [UICollectionViewLayoutAttributeslayoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithIndexPath:[NSIndexPathindexPathWithIndex:0]];
& & layoutHeader.frame =CGRectMake(0,0,
screenW, self.sectionEdge.top);
& & [self.attributeArrayaddObject:layoutHeader];
& & //item内容视图
& & NSInteger count = [self.collectionViewnumberOfItemsInSection:0];
& & for (int i =0; i & i ++) {
& & & & UICollectionViewLayoutAttributes * attribute = [selflayoutAttributesForItemAtIndexPath:[NSIndexPathindexPathForRow:i
inSection:0]];
& & & & [self.attributeArrayaddObject:attribute];
controllerView中要注册Cell和头,这里的cell和头都是自定义的,
[_communityCollectionViewregisterClass:[CommunityCollectionViewCellclass]forCellWithReuseIdentifier:@&CollectionCell&];
& & [_communityCollectionViewregisterClass:[CommunityHeaderViewclass]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@&HeaderView&];
在拿到请求数据的地方调用该方法为自定义的瀑布流Layout设置高度回调,里面的方法是根据数据内容来计算布局高度的,这个根据自己的内容来计算。
#pragma mark - 计算Item高度回调
- (void)counterItemHightByCommunityDataArray:(NSArray *)dataArray
& & _communityLayout.itemHightBlock = ^CGFloat
(NSIndexPath * index,CGFloat width){
& & & & CGFloat itemH = [cellHCountercountCellHightByCommunityData:communityDataArray[index.item]];
& & & & return itemH;
然后collectionView的Heard头视图设置代理就可以走了,设置一下自定义的头视图,
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString
*)kind atIndexPath:(NSIndexPath *)indexPath
& & UICollectionReusableView * reusableview =nil;
& & if (kind ==UICollectionElementKindSectionHeader){
& & & & _heardView = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@&HeaderView&forIndexPath:indexPath];
& & & & reusableview = _heardView;
& & return
好了,关键的代码就这些了。
本文已收录于以下专栏:
相关文章推荐
一、UICollection
瀑布流现在好像挺流行,怎么实现呢
用UICollectionView咯,还是先说这个集合视图吧
这个继承于UIScrollView,可以滚动,
UICollectio...
//自定义cell
//自定义表头和表尾
//根据原图片自定义cell的高度
#import "RootViewController.h"#import
"GirlCollec...
iOS开发UI篇—自定义瀑布流控件(cell的循环利用)
一、简单说明
  当滚动的时候,向数据源要cell。
  当UIScrollView滚动的时候会调用layout...
iOS开发UI篇—自定义瀑布流控件(cell的事件处理)
一、关于cell的复用的补充
在设置每个索引位置对应的cell的方法中,打印cell的索引和地址,已查看cell的循环利用情况
要做瀑布流,首先要清楚几点:主要是对 UICollectionViewLayout 子类的编写。第一步、自定义初始化(主要是参数的初始化,行数numberOfLine,行间距rowGap,列间距lin...
一直以来都想研究瀑布流的具体实现方法(起因是因为一则男女程序员应聘的笑话,做程序的朋友应该都知道)。最近学习到了瀑布流的实现方法,瀑布流的实现方式有多种,这里应用collectionView来重写其U...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 ioscollectionview 的文章

 

随机推荐