UICollectionView 瀑布流 添加表头视图的坑

首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView的表头只要设置tableview.tableHeaderView就可以了. collectionView 怎么添加这样的效果的呢

有两种思路

第一种:在collectionView的段头代理中设置 (只在第一段中设置)

第二种:改变 collectionView 的内延距离, 然后添加在内延空白的位置.

第一种

  1. // 返回头视图
  2. - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
  3. {
  4. UICollectionReusableView *reusableView =nil;
  5. //返回段头段尾视图
  6. if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
  7. HMCollectionReusableView *header=[collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:headerViewIdentifier forIndexPath:indexPath];
  8. //添加头视图的内容
  9. header.backgroundColor = [UIColor redColor];
  10. reusableView = header;
  11. return reusableView;
  12. }
  13. //如果底部视图
  14. if (kind ==UICollectionElementKindSectionFooter)
  15. {
  16. UICollectionReusableView *footerview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"FooterView"forIndexPath:indexPath];
  17. footerview.backgroundColor = [UIColor purpleColor];
  18. reusableView = footerview;
  19.  
  20. }
  21. return reusableView;
  22. }

但是你会发现,使用瀑布流的时候,,Cell都是不同大小的布局,UICollectionViewFlowLayout是自定义的布局,collectionView的代理不会走,所以,这里就比较坑了。

怎么解决呢 就是在自定义的Layout中添加加一个 Header类型的 UICollectionViewLayoutAttributes就可以。然后我把瀑布流的Cell的起始位置从headerView的最大Y开始布局。这样设置之后,controllerView中的代理方法才会走,要记得注册头视图哦,不然会崩。

注册段头

  1. //注册段头部视图
  2. [collectionView registerClass:[HMCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerViewIdentifier];

    //xib

    [collectionView registerNib:[UINib nibWithNibName:@"HMCollectionReusableView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerViewIdentifier];

自定义的布局 HMWaterflowLayout : UICollectionViewLayout

.h

  1. @interface HMWaterflowLayout : UICollectionViewLayout
  2.  
  3. @property (nonatomic, assign) UIEdgeInsets sectionInset;
  4. /** 段头的size */
  5. @property (nonatomic, assign) CGSize headerReferenceSize;
  6.  
  7. /** 每一列之间的间距 */
  8. @property (nonatomic, assign) CGFloat columnMargin;
  9. /** 每一行之间的间距 */
  10. @property (nonatomic, assign) CGFloat rowMargin;
  11. /** 显示多少列 */
  12. @property (nonatomic, assign) int columnsCount;
  13.  
  14. @property (nonatomic, weak) id<HMWaterflowLayoutDelegate> delegate;
  15.  
  16. @end

.m

  1. #import <UIKit/UIKit.h>
  2. @class HMWaterflowLayout;
  3.  
  4. @protocol HMWaterflowLayoutDelegate <NSObject>
  5. - (CGFloat)waterflowLayout:(HMWaterflowLayout *)waterflowLayout heightForWidth:(CGFloat)width atIndexPath:(NSIndexPath *)indexPath;
  6. @end#import "HMWaterflowLayout.h"
  7.  
  8. @interface HMWaterflowLayout();
  9. /** 这个字典用来存储每一列最大的Y值(每一列的高度) */
  10. @property (nonatomic, strong) NSMutableDictionary *maxYDict;
  11.  
  12. /** 存放所有的布局属性 */
  13. @property (nonatomic, strong) NSMutableArray *attrsArray;
  14. @end
  15.  
  16. @implementation HMWaterflowLayout
  17.  
  18. - (NSMutableDictionary *)maxYDict
  19. {
  20. if (!_maxYDict) {
  21. self.maxYDict = [[NSMutableDictionary alloc] init];
  22. }
  23. return _maxYDict;
  24. }
  25.  
  26. - (NSMutableArray *)attrsArray
  27. {
  28. if (!_attrsArray) {
  29. self.attrsArray = [[NSMutableArray alloc] init];
  30. }
  31. return _attrsArray;
  32. }
  33.  
  34. - (instancetype)init
  35. {
  36. if (self = [super init]) {
  37. self.columnMargin = ;
  38. self.rowMargin = ;
  39. self.sectionInset = UIEdgeInsetsMake(, , , );
  40. self.columnsCount = ;
  41. //如果段头的高度不一致 可以仿照UICollectionViewFlowLayout的代理 自己写一个代理方法返回 CGSize
  42. self.headerReferenceSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, );
  43. }
  44. return self;
  45. }
  46.  
  47. - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
  48. {
  49. return YES;
  50. }
  51.  
  52. /**
  53. * 每次布局之前的准备
  54. */
  55. - (void)prepareLayout
  56. {
  57. [super prepareLayout];
  58.  
  59. // 1.清空最大的Y值
  60. [self.maxYDict removeAllObjects];
  61.  
  62. for (int i = ; i<self.columnsCount; i++) {
  63. NSString *column = [NSString stringWithFormat:@"%d", i];
  64. self.maxYDict[column] = @(self.sectionInset.top);
  65. }
  66.  
  67. // 2.计算所有cell的属性
  68. [self.attrsArray removeAllObjects];
  69.  
  70. //头部视图
  71. UICollectionViewLayoutAttributes * layoutHeader = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathWithIndex:]];
  72. layoutHeader.frame =CGRectMake(,, self.headerReferenceSize.width, self.headerReferenceSize.height);
  73. [self.attrsArray addObject:layoutHeader];
  74.  
  75. //item内容视图
  76. NSInteger count = [self.collectionView numberOfItemsInSection:];
  77. for (int i = ; i<count; i++) {
  78. UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:]];
  79. [self.attrsArray addObject:attrs];
  80. }
  81. }
  82.  
  83. /**
  84. * 返回所有的尺寸
  85. */
  86. - (CGSize)collectionViewContentSize
  87. {
  88. __block NSString *maxColumn = @"";
  89. [self.maxYDict enumerateKeysAndObjectsUsingBlock:^(NSString *column, NSNumber *maxY, BOOL *stop) {
  90. if ([maxY floatValue] > [self.maxYDict[maxColumn] floatValue]) {
  91. maxColumn = column;
  92. }
  93. }];
  94.  
  95. //包括段头headerView的高度
  96. return CGSizeMake(, [self.maxYDict[maxColumn] floatValue] + self.sectionInset.bottom + self.headerReferenceSize.height );
  97. }
  98.  
  99. /**
  100. * 返回indexPath这个位置Item的布局属性
  101. */
  102. - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
  103. {
  104. // 假设最短的那一列的第0列
  105. __block NSString *minColumn = @"";
  106. // 找出最短的那一列
  107. [self.maxYDict enumerateKeysAndObjectsUsingBlock:^(NSString *column, NSNumber *maxY, BOOL *stop) {
  108. if ([maxY floatValue] < [self.maxYDict[minColumn] floatValue]) {
  109. minColumn = column;
  110. }
  111. }];
  112.  
  113. // 计算尺寸
  114. CGFloat width = (self.collectionView.frame.size.width - self.sectionInset.left - self.sectionInset.right - (self.columnsCount - ) * self.columnMargin)/self.columnsCount;
  115. CGFloat height = [self.delegate waterflowLayout:self heightForWidth:width atIndexPath:indexPath];
  116.  
  117. // 计算位置
  118. CGFloat x = self.sectionInset.left + (width + self.columnMargin) * [minColumn intValue];
  119. CGFloat y = [self.maxYDict[minColumn] floatValue] + self.rowMargin;
  120.  
  121. // 更新这一列的最大Y值
  122. self.maxYDict[minColumn] = @(y + height);
  123.  
  124. // 创建属性
  125. UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
  126.  
  127. //把瀑布流的Cell的起始位置从headerView的最大Y开始布局
  128. attrs.frame = CGRectMake(x, self.headerReferenceSize.height + y, width, height );
  129. return attrs;
  130. }
  131.  
  132. /**
  133. * 返回rect范围内的布局属性
  134. */
  135. - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
  136. {
  137. return self.attrsArray;
  138. }
  139.  
  140. @end

第二种

  1. self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(, , , self.view.frame.size.height) collectionViewLayout:flowlayout];
  2. self.collectionView.contentInset = UIEdgeInsetsMake(, , , );
  3. UIImageView *imagev = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"015.png"]];
  4. imagev.frame = CGRectMake(, -, , );
  5. [self.collectionView addSubview: imagev];
  6. [self.view addSubview: _collectionView];

提示: UICollectionReusableView 段头是可以自定义的 第一种比较好

注意:UITableView 有两个样式布局 1.Group 2.Plain (段头可以停留) 而UICollectionView 需要自己写布局 要想实现Plain (段头可以停留)的效果可以找一些网上的第三方的框架参考一下

iOS - UICollectionView 瀑布流 添加表头视图的坑的更多相关文章

  1. iOS横向瀑布流的封装

    前段时间, 做一个羡慕, 需要使用到瀑布流! 说道瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从scrollView 到 tableView 书写的瀑布流, 然后再到2012年iOS6 苹 ...

  2. ios图片瀑布流代码

    ios瀑布流,实现简单的瀑布流视图布局,可以显示网络图片,下拉刷新,上拉加载更多. 下载:http://www.huiyi8.com/sc/9087.html

  3. ios开发瀑布流框架的应用

    一:瀑布流框架的应用:将封装好的瀑布流框架导入,遵守协议 二:代码: #import "HMShopsViewController.h" #import "HMShopC ...

  4. ios开发瀑布流框架的封装

    一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...

  5. UICollectionView瀑布流的实现原理(转)

    http://ios.jobbole.com/85689/ 和使用 UIScollView 创刊一个瀑布流是一样的方式 7cc829d3gw1f4nq2oc09zj20j00hvq90.jpg 我的 ...

  6. iOS基础 - 瀑布流

    一.瀑布流简介 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pint ...

  7. iOS开发瀑布流的实现

    //自定义布局,继承于UICollectionViewLayout #import <UIKit/UIKit.h> @class WaterFlowLayout; @protocol  W ...

  8. 【iOS开发】动态添加子视图 UIView 的正确方法

    很多时候哥比较喜欢用代码添加视图,特别是要同时加很多UIView时,而且跟 xib 比起来代码更容易管理,在多人的项目中代码不容易 conflict. 但小牛哥最近发现很多新人都不太清楚正确的使用方法 ...

  9. 第二十九篇、UICollectionView瀑布流

    1.实现思路 >第一种方案:UIScrollView 镶嵌三个UITableView (不推荐使用) >第二种方案:UIScrollView 镶嵌UIImageView (需要解决循环利用 ...

随机推荐

  1. struts2客户端与服务器端即jsp页面与action之间的关系

    在Struts2中,客户端和服务器之间的数据传输全部要用到get.set方法:用set方法 ,可以将表单中的值存入Action类.通过Struts2.0标签,调用get方法将Action类中的结果数据 ...

  2. Mysql 8.0.11版本,安装成功,使用Navicat连接失败。

    Note:本文只针对mac!! 问题 安装mysql成功之后,想自己弄个数据库试试,但是报错.并不是错误代号,而是一段代码: Authentication plugin 'caching_sha2_p ...

  3. MySQL中information_schema是什么

    转载地址:http://help.wopus.org/mysql-manage/607.html 大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_sche ...

  4. VMware克隆虚拟机后无法启动网卡

    最简单的办法: 修改这个文件:/etc/udev/rules.d/70_persistent-net.rules 把eth1修改为eth0,记下里面的mac地址 修改/etc/sysconfig/ne ...

  5. C# 大图片压缩算法,减少图片体积

    声明: 图片压缩算法,不建议对小图片进行压缩,一般文件小于1m的,真心没必要压缩, 图片很小的,例如:几百KB的图片,有可能不会减少图片体积,反而压缩后更大,也很正常, 请大家合理使用,并不是,所有图 ...

  6. Kong安装简介

    评价:其实是一个整合型的方案,从它的安装页面看:http://getkong.org/download/#other该方案基于OpenResty,和lua 提供的功能是统一的Oauth认证.rest封 ...

  7. Mac下终端使用密钥登录服务器

    可行方法: mac终端输入 ssh-keygen 因为mac系统是类unix系统,linux系统是unix系统演变来的,所以呢,相当于在一个linux系统登录另外一个linux系统, 基本命令还是一样 ...

  8. 调整iRedmail之Roundcube webmail服务不可不知的几件事

    iRedMail集成了roundcube webmail,极大的方便了安装维护工作,但是需求是千遍万化的,总有需要深入调整的地方.下面就是我调整roundcube时遇到的几点问题: 一.修改网页标题p ...

  9. UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数

    lienhua342014-09-16 1 文件的时间 每个文件都有三个时间字段,如表 1 所示. 表 1: 文件的三个时间字段 说明 字段 st_atime 文件数据的最后访问时间 st_mtime ...

  10. UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构

    lienhua342014-08-27 内核使用三种数据结构表示打开的文件,分别是文件描述符表.文件表和 V 节点表. (1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每 ...