UICollectionView基础

 

初始化部分:

UICollectionViewFlowLayout *flowLayout= [[UICollectionViewFlowLayout alloc]init];
self.myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(20, 20, 250, 350) collectionViewLayout:flowLayout];
self.myCollectionView.backgroundColor = [UIColor grayColor];
[self.myCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@“myCell"];
self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self; [self.view addSubview:self.myCollectionView];

UICollectionViewLayout

UICollectionViewLayout决定了UICollectionView如何显示在界面上,Apple提供了一个最简单的默认layout对象:UICollectionViewFlowLayout。

Flow Layout是一个Cells的线性布局方案,并具有页面和页脚。其可定制的内容如下:

itemSize属性

设定全局的Cell尺寸,如果想要单独定义某个Cell的尺寸,可以使用下面方法:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

minimumLineSpacing属性

设定全局的行间距,如果想要设定指定区内Cell的最小行距,可以使用下面方法:

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

minimumInteritemSpacing属性

设定全局的Cell间距,如果想要设定指定区内Cell的最小间距,可以使用下面方法:

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

scrollDirection属性

设定滚动方向,有UICollectionViewScrollDirectionVertical和UICollectionViewScrollDirectionHorizontal两个值。

headerReferenceSize属性与footerReferenceSize属性

设定页眉和页脚的全局尺寸,需要注意的是,根据滚动方向不同,header和footer的width和height中只有一个会起作用。如果要单独设置指定区内的页面和页脚尺寸,可以使用下面方法:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section

sectionInset属性

设定全局的区内边距,如果想要设定指定区的内边距,可以使用下面方法:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;


然后需要实现三种类型的委托:UICollectionViewDataSource, UICollectionViewDelagate和UICollectionViewDelegateFlowLayout。

@interface ViewController : UIViewController <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>

因为UICollectionViewDelegateFlowLayout实际上是UICollectionViewDelegate的一个子协议,它继承了UICollectionViewDelegate,所以只需要在声明处写上UICollectionViewDelegateFlowLayout就行了。


UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

返回collection view里区(section)的个数,如果没有实现该方法,将默认返回1:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 2;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

返回指定区(section)包含的数据源条目数(number of items),该方法必须实现:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 7;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

返回某个indexPath对应的cell,该方法必须实现:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
if(indexPath.section==0)
{
cell.backgroundColor = [UIColor redColor];
}
else if(indexPath.section==1)
{
cell.backgroundColor = [UIColor greenColor];
}
return cell;
}

UICollectionViewCell结构上相对比较简单,由下至上:

  • 首先是cell本身作为容器view
  • 然后是一个大小自动适应整个cell的backgroundView,用作cell平时的背景
  • 再其次是selectedBackgroundView,是cell被选中时的背景
  • 最后是一个contentView,自定义内容应被加在这个view上

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath

为collection view添加一个补充视图(页眉或页脚)

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

设定页眉的尺寸

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section

设定页脚的尺寸

- (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier

添加页眉和页脚以前需要注册类和标识:


添加补充视图的代码示例:

[self.myCollectionView registerClass:[MyHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader"];
[self.myCollectionView registerClass:[MyHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwHeader"]; -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
CGSize size = {240,25};
return size;
} -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
{
CGSize size = {240,25};
return size;
} - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
MyHeadView *headView; if([kind isEqual:UICollectionElementKindSectionHeader])
{
headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];
[headView setLabelText:[NSString stringWithFormat:@"section %d's header",indexPath.section]];
}
else if([kind isEqual:UICollectionElementKindSectionFooter])
{
headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];
[headView setLabelText:[NSString stringWithFormat:@"section %d's footer",indexPath.section]];
}
return headView;
}

MyHeadView.h

#import <UIKit/UIKit.h>

@interface MyHeadView : UICollectionReusableView
- (void) setLabelText:(NSString *)text;
@end

MyHeadView.m

#import "MyHeadView.h"

@interface MyHeadView()

@property (strong, nonatomic) UILabel *label;

@end

@implementation MyHeadView

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.label = [[UILabel alloc] init];
self.label.font = [UIFont systemFontOfSize:18];
[self addSubview:self.label];
}
return self;
} - (void) setLabelText:(NSString *)text
{
self.label.text = text;
[self.label sizeToFit];
} @end

在注册Cell和补充视图时,也可以用新建xib文件的方式:

[self.myCollectionView registerNib:[UINib nibWithNibName:@"MyCollectionCell" bundle:nil] forCellWithReuseIdentifier:@"hxwCell"];

[self.myCollectionView registerNib:[UINib nibWithNibName:@"MySupplementaryView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader"];

[self.myCollectionView registerNib:[UINib nibWithNibName:@"MySupplementaryView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwFooter"];

用这种方式注册后,甚至可以不用新建类去绑定这个xib,直接通过viewWithTag的方式获取xib里的控件:

UICollectionReusableView *view =  [collectionView dequeueReusableSupplementaryViewOfKind :kind withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];

UILabel *label = (UILabel *)[view viewWithTag:1];

label.text = @"empty";

UICollectionViewDelegateFlowLayout

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

设定指定Cell的尺寸

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0 && indexPath.row==1)
{
return CGSizeMake(50, 50);
}
else
{
return CGSizeMake(75, 30);
}
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

设定collectionView(指定区)的边距

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
if(section==0)
{
return UIEdgeInsetsMake(35, 25, 15, 25);
}
else
{
return UIEdgeInsetsMake(15, 15, 15, 15);
}
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

设定指定区内Cell的最小行距,也可以直接设置UICollectionViewFlowLayout的minimumLineSpacing属性

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
if(section==0)
{
return 10.0;
}
else
{
return 20.0;
}
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

设定指定区内Cell的最小间距,也可以直接设置UICollectionViewFlowLayout的minimumInteritemSpacing属性

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
if(section==0)
{
return 10.0;
}
else
{
return 20.0;
}
}

UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

当指定indexPath处的item被选择时触发

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self.myArray removeObjectAtIndex:indexPath.row]; [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
}

P.s. 当你删除或添加元素时,一定要更新numberOfItemsInSection的返回情况。

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath

当指定indexPath处的item被取消选择时触发,仅在允许多选时被调用

下面是三个和高亮有关的方法:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath

事件的处理顺序如下:

  1. 手指按下
  2. shouldHighlightItemAtIndexPath (如果返回YES则向下执行,否则执行到这里为止)
  3. didHighlightItemAtIndexPath (高亮)
  4. 手指松开
  5. didUnhighlightItemAtIndexPath (取消高亮)
  6. shouldSelectItemAtIndexPath (如果返回YES则向下执行,否则执行到这里为止)
  7. didSelectItemAtIndexPath (执行选择事件)

如果只是简单实现点击后cell改变显示状态,只需要在cellForItemAtIndexPath方法里返回cell时,指定cell的selectedBackgroundView:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath]; UIView* selectedBGView = [[UIView alloc] initWithFrame:cell.bounds];
selectedBGView.backgroundColor = [UIColor blueColor];
cell.selectedBackgroundView = selectedBGView; return cell;
}

如果要实现点击时(手指未松开)的显示状态与点击后(手指松开)的显示状态,则需要通过上面提到的方法来实现:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
} - (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath]; [cell setBackgroundColor:[UIColor purpleColor]];
} - (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath]; [cell setBackgroundColor:[UIColor yellowColor]];
}

UIColletionView 的属性与常用方法介绍的更多相关文章

  1. winFrom 常用控件属性及方法介绍

    目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文本框)控件 4.RichTextBox控件 5.NumericUpDown控件 6.Button(按钮)控件 7.Gro ...

  2. Moq 测试 属性,常用方法

    RhinoMock入门(7)——Do,With和Record-playback 摘要: (一)Do(delegate)有时候在测试过程中只返回一个静态的值是不够的,在这种情况下,Do()方法可以用来在 ...

  3. C# 常用控件属性及方法介绍

      C#常用控件属性及方法介绍                                               目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox ...

  4. java基础-System类常用方法介绍

    java基础-System类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.System类概念 在API中system类介绍的比较简单,我们给出定义,system中 ...

  5. 线程池ThreadPool的常用方法介绍

    线程池ThreadPool的常用方法介绍 如果您理解了线程池目的及优点后,让我们温故下线程池的常用的几个方法: 1. public static Boolean QueueUserWorkItem(W ...

  6. 【转载】C#常用控件属性及方法介绍

    C#常用控件属性及方法介绍                                               目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文 ...

  7. 实例级别和类级别的static、构造函数、字段属性的简单介绍

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 实例级别 ...

  8. UploadifyAPI-上传插件属性和方法介绍

    上一篇文章简单的介绍了Uploadify上传插件的使用.但是对于常用的属性和方法并没有说明.授人以鱼不如授人以渔,我决定将常用的属性列举出来,供大伙参考参考.           Uploadify属 ...

  9. object-fit 属性的用法介绍

    这个要在宽,高都是100%的情况下才能提现 object-fit 属性的用法介绍 fill(不保持纵横比缩放图片,使图片完全适应) contain(保持纵横比缩放图片,使图片的长边能完全显示出来) c ...

随机推荐

  1. ViewPager部分源码分析二:FragmentManager对Fragment状态的管理完成ViewPager的child添加或移出

    ViewPager维护child代码流程: 注:PagerAdapter 使用的是FragmentPagerAdapter类或者它的子类. viewPager.populate(): void pop ...

  2. 【转载】PHP使用1个crontab管理多个crontab任务

    转载来自: http://www.cnblogs.com/showker/archive/2013/09/01/3294279.html http://www.binarytides.com/php- ...

  3. java-解决业务操可能数据冲突问题

    问题提出,由于业务会出现多人同时操作,或者业务人员反复的操作,因此在业务流程中,需要对业务操作数据进行保护,由于使用数据库锁可能会引起一些难以预料的问题,因此考虑使用内存锁,设计思想:在内存中使用一个 ...

  4. apache lucene solr 官网历史版本下载地址

    官网上一般只提供最新版本的下载,下面两个链接为所有历史版本的下载地址: lucene地址:archive.apache.org/dist/lucene/java/ solr地址:archive.apa ...

  5. go sample - mongodb

    简单的mongodb 操作 package mainimport ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2 ...

  6. JS判断输入值是否为正整数

    JS中的test是原来是JS中检测字符串中是否存在的一种模式,JS输入值是否为判断正整数代码: <script type=”text/javascript”> function test( ...

  7. linux SecureCRT ssh key认证登陆

    转自:http://blog.chinaunix.net/uid-20639775-id-3207171.html 通过SecureCRT创建key登录认证 一.生成公钥/密钥对 使用SecureCR ...

  8. Sublime Text3 配置Node.js运行命令

    ­ 在Sublime Text中可以很容易配置新的编译运行命令,下面的截图是汉化版的中文菜单,英文菜单请直接对照. 首先需要在本地安装Node,默认的Node会加入到系统的环境变量,这样执行Node命 ...

  9. poj 3468【线段树】

    题意:给定Q(1<=Q<=100000)个数A1,A2…AQ,以及可能多次进行的两个操作 1)对某个区间Ai……Aj的每个数都加n(n可变) 2)对某个区间Ai……Aj的数求和 分析: 树 ...

  10. Android LayoutInflater详解(转)

    在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例 ...