UICollectionView(一)基本概念
2015-11-03 15:49
405 查看
整体预览
高等级的包含和管理(Top-level containment and management)
UICollectionView
UICollectionViewController
UICollectionView对象为collection view的内容定义了显示的区域。该类是 UIScrollView的子类,能够拥有大量的滚动区域,同时该类能够更具布局对象的布局信息,非常方便的显示数据。
UICollectionViewController对象提供视图控制器等级的管理支持,根据需求可以选择是否使用。
内容管理(Content management)
UICollectionViewDataSource
UICollectionViewDelegate
数据源对象( data source object)是与collection view相关联的最重要对象,并且我们必须提供。该对象管理着collection view的内容并且创建视图显示内容。为了实现数据源对象,我们必须创建一个对象遵守UICollectionViewDataSource协议。
UICollectionView的代理对象能够让我们拦截来自collection view有趣的信息并且自定义view的行为。例如:我们使用代理对象来跟踪在collection view中选中和高亮的item对象,不像数据源对象,代理对象是可选的。对于跟多的信息,可以看Designing Your Data Source and Delegate.
显示内容(Presentation)
UICollectionReusableView
UICollectionViewCell
所有显示在UICollectionView中的views都必须是UICollectionReusableView类的实例。通过使用UICollectionView该类支持循环机制。重复利用视图将提高整体的性能,特别是滚动的流畅。
UICollectionViewCell 对象是具体类型的重用视图,用于展示我们的数据。
布局(Layout)
UICollectionViewLayout
UICollectionViewLayoutAttributes
UICollectionViewUpdateItem
UICollectionViewLayout和子类作为布局对象主要负责定义位置、大小、cell的可视属性,以及collection view中重用的视图。
在布局过程中,一个布局对象(layout objects)将创建布局属性对象(layout attribute objects),该属性对象是UICollectionViewLayoutAttributes类的实例,它将告诉collection view在哪里以及怎样显示cells和重用视图。
无论什么时候数据item在collection view中进行插入 (inserted)、删除(deleted)、移动(move),布局对象接受UICollectionViewUpdateItem类的实例,我们从未使用该类自己创建实例。对于更多有关布局对象信息,可以看 The Layout Object Controls the Visual Presentation.
流动布局(Flow layout)
UICollectionViewFlowLayout
UICollectionViewDelegateFlowLayout
UICollectionViewFlowLayout类是具体的布局对象,能够用于实现网格或者其它基于线性的布局。我们能够直接使用该类,或者设置flow代理,UICollectionViewDelegateFlowLayout协议中提供了大量的方法来方便我们自定义布局信息。
下图显示了核心对象与collection view之间的关系。collection view从数据源(data source )获取cells显示的相关信息。数据源(data source)和代理(delegate)对象需要APP提供自定义对象并用于管理内容,包括选中和高亮的cells。布局对象(layout object)主要负责确定cell的位置,并且通过提供一个或者多个布局属性对象发送相关信息给collection view,collection view将布局信息与cell合并创建最终的可视界面。
Figure 1-1 Merging content and layout to create the final presentation
![](http://img.blog.csdn.net/20161115145154017)
什么是UICollectionView?
UICollectionView是一种新的数据展示方式,简单来说可以把他理解成多列的UITableView.
标准的UICollectionView包含三个部分,它们都是UIView的子类:
Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容.
Supplementary Views 追加视图可以理解为每个Section的Header或者Footer,用来标记每个section的view.
Decoration Views 装饰视图 这是每个section的背景.
与UITableView的对比:
UITableView是iOS开发中的非常重要的一个类,对这个类应该是非常熟悉了。实现一个UICollectionView和实现一个UITableView基本没有什么大区别,它们都同样是datasource和delegate设计模式的:datasource为view提供数据源,告诉view要显示些什么东西以及如何显示它们,delegate提供一些样式的小细节以及用户交互的相应。
UICollectionViewDataSource中:
section的数量 -numberOfSectionsInCollection:
某个section里有多少个item -collectionView:numberOfItemsInSection:
对于某个位置应该显示什么样的cell -collectionView:cellForItemAtIndexPath:
实现以上三个委托方法,基本上就可以保证CollectionView工作正常了。
当然,还有提供Supplementary View的方法.collectionView:viewForSupplementaryElementOfKind:atIndexPath:
对于Decoration Views,提供方法并不在UICollectionViewDataSource中,而是直接UICollectionViewLayout类中的(因为它仅仅是视图相关,而与数据无关).
关于重用问题
为了得到高效的View,对于cell的重用是必须的,避免了不断生成和销毁对象的操作,这与在UITableView中的情况是一致的。但值得注意的时,在UICollectionView中,不仅cell可以重用,Supplementary View和Decoration View也是可以并且应当被重用的。在iOS5中,Apple对UITableView的重用做了简化,以往要写类似这样的代码:
而如果我们在TableView向数据源请求数据之前使用-registerNib:forCellReuseIdentifier:方法为@“cell”注册过nib的话,就可以省下每次判断并初始化cell的代码,要是在重用队列里没有可用的cell的话,runtime将自动帮我们生成并初始化一个可用的cell。
这个特性很受欢迎,因此在UICollectionView中Apple继承使用了这个特性,并且把其进行了一些扩展。使用以下方法进行注册:
-registerClass:forCellWithReuseIdentifier:
-registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
-registerNib:forCellWithReuseIdentifier:
-registerNib:forSupplementaryViewOfKind:withReuseIdentifier
相比UITableView有两个主要变化:一是加入了对某个Class的注册,这样即使不用提供nib而是用代码生成的view也可以被接受为cell了;二是不仅只是cell,Supplementary View也可以用注册的方法绑定初始化了。在对collection view的重用ID注册后,就可以像UITableView那样简单的写cell配置了:
UICollectionViewDelegate
数据无关的view的外形啊,用户交互的,由UICollectionViewDelegate来负责:
cell的高亮
cell的选中状态
可以支持长按后的菜单
关于用户交互,UICollectionView也做了改进。每个cell现在有独立的高亮事件和选中事件的delegate,用户点击cell的时候,现在会按照以下流程向delegate进行询问:
-collectionView:shouldHighlightItemAtIndexPath: 是否应该高亮?
-collectionView:didHighlightItemAtIndexPath: 如果1回答为是,那么高亮
-collectionView:shouldSelectItemAtIndexPath: 无论1结果如何,都询问是否可以被选中?
-collectionView:didUnhighlightItemAtIndexPath: 如果1回答为是,那么现在取消高亮
-collectionView:didSelectItemAtIndexPath: 如果3回答为是,那么选中cell
状态控制要比以前灵活一些,对应的高亮和选中状态分别由highlighted和selected两个属性表示。
使用UICollectionViewFlowLayout定制对象布局:
创建UICollectionViewFlowLayout布局对象.如果直接使用UICollectionViewFlowLayout布局对象来管理UICollectionView的所有单元格,那么这些单元格德大小,间距和行距都是相同的.那么可以实现非常整齐的网格效果.
但是在某些时候,UICollectionView控件中各个单元格的大小参差不齐,如果强行就爱那个这些控件缩放到统一大小,势必会影响效果.如果程序需要让UICollectionView中各控件各自显示不同的大小,则可借助于UICollectionViewDelegateFlowLayout协议来实现.该UICollectionViewDelegateFlowLayout协议继承于UICollectionViewDelegate,因此实现该协议对象可以当做UICollectionView的委托对象使用.UICollectionViewDelegateFlowLayout协议定义了如下方法:
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;该方法返回的CGSize对象将指定控制NSIndexPath对应单元格的大小.
(UIEdgeInsets)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
该方法返回UIEdgeInsets对象控制指定分区上下左右空白大小.
(CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
该方法返回的长度值将控制指定分区内最小的行间距.
(CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
该方法返回的长度值将控制指定分区内最小的列间距.
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
该方法返回的CGSize将控制指定分区头的大小
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
该方法返回的CGSize将控制指定分区尾部的大小单使用一下:
下面一起来简单的使用一下:
实现效果如下:简单的网格布局界面
高等级的包含和管理(Top-level containment and management)
UICollectionView
UICollectionViewController
UICollectionView对象为collection view的内容定义了显示的区域。该类是 UIScrollView的子类,能够拥有大量的滚动区域,同时该类能够更具布局对象的布局信息,非常方便的显示数据。
UICollectionViewController对象提供视图控制器等级的管理支持,根据需求可以选择是否使用。
内容管理(Content management)
UICollectionViewDataSource
UICollectionViewDelegate
数据源对象( data source object)是与collection view相关联的最重要对象,并且我们必须提供。该对象管理着collection view的内容并且创建视图显示内容。为了实现数据源对象,我们必须创建一个对象遵守UICollectionViewDataSource协议。
UICollectionView的代理对象能够让我们拦截来自collection view有趣的信息并且自定义view的行为。例如:我们使用代理对象来跟踪在collection view中选中和高亮的item对象,不像数据源对象,代理对象是可选的。对于跟多的信息,可以看Designing Your Data Source and Delegate.
显示内容(Presentation)
UICollectionReusableView
UICollectionViewCell
所有显示在UICollectionView中的views都必须是UICollectionReusableView类的实例。通过使用UICollectionView该类支持循环机制。重复利用视图将提高整体的性能,特别是滚动的流畅。
UICollectionViewCell 对象是具体类型的重用视图,用于展示我们的数据。
布局(Layout)
UICollectionViewLayout
UICollectionViewLayoutAttributes
UICollectionViewUpdateItem
UICollectionViewLayout和子类作为布局对象主要负责定义位置、大小、cell的可视属性,以及collection view中重用的视图。
在布局过程中,一个布局对象(layout objects)将创建布局属性对象(layout attribute objects),该属性对象是UICollectionViewLayoutAttributes类的实例,它将告诉collection view在哪里以及怎样显示cells和重用视图。
无论什么时候数据item在collection view中进行插入 (inserted)、删除(deleted)、移动(move),布局对象接受UICollectionViewUpdateItem类的实例,我们从未使用该类自己创建实例。对于更多有关布局对象信息,可以看 The Layout Object Controls the Visual Presentation.
流动布局(Flow layout)
UICollectionViewFlowLayout
UICollectionViewDelegateFlowLayout
UICollectionViewFlowLayout类是具体的布局对象,能够用于实现网格或者其它基于线性的布局。我们能够直接使用该类,或者设置flow代理,UICollectionViewDelegateFlowLayout协议中提供了大量的方法来方便我们自定义布局信息。
下图显示了核心对象与collection view之间的关系。collection view从数据源(data source )获取cells显示的相关信息。数据源(data source)和代理(delegate)对象需要APP提供自定义对象并用于管理内容,包括选中和高亮的cells。布局对象(layout object)主要负责确定cell的位置,并且通过提供一个或者多个布局属性对象发送相关信息给collection view,collection view将布局信息与cell合并创建最终的可视界面。
Figure 1-1 Merging content and layout to create the final presentation
什么是UICollectionView?
UICollectionView是一种新的数据展示方式,简单来说可以把他理解成多列的UITableView.
标准的UICollectionView包含三个部分,它们都是UIView的子类:
Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容.
Supplementary Views 追加视图可以理解为每个Section的Header或者Footer,用来标记每个section的view.
Decoration Views 装饰视图 这是每个section的背景.
与UITableView的对比:
UITableView是iOS开发中的非常重要的一个类,对这个类应该是非常熟悉了。实现一个UICollectionView和实现一个UITableView基本没有什么大区别,它们都同样是datasource和delegate设计模式的:datasource为view提供数据源,告诉view要显示些什么东西以及如何显示它们,delegate提供一些样式的小细节以及用户交互的相应。
UICollectionViewDataSource中:
section的数量 -numberOfSectionsInCollection:
某个section里有多少个item -collectionView:numberOfItemsInSection:
对于某个位置应该显示什么样的cell -collectionView:cellForItemAtIndexPath:
实现以上三个委托方法,基本上就可以保证CollectionView工作正常了。
当然,还有提供Supplementary View的方法.collectionView:viewForSupplementaryElementOfKind:atIndexPath:
对于Decoration Views,提供方法并不在UICollectionViewDataSource中,而是直接UICollectionViewLayout类中的(因为它仅仅是视图相关,而与数据无关).
关于重用问题
为了得到高效的View,对于cell的重用是必须的,避免了不断生成和销毁对象的操作,这与在UITableView中的情况是一致的。但值得注意的时,在UICollectionView中,不仅cell可以重用,Supplementary View和Decoration View也是可以并且应当被重用的。在iOS5中,Apple对UITableView的重用做了简化,以往要写类似这样的代码:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (!cell) { //如果没有可重用的cell,那么生成一个 cell = [[UITableViewCell alloc] init]; } return cell
而如果我们在TableView向数据源请求数据之前使用-registerNib:forCellReuseIdentifier:方法为@“cell”注册过nib的话,就可以省下每次判断并初始化cell的代码,要是在重用队列里没有可用的cell的话,runtime将自动帮我们生成并初始化一个可用的cell。
这个特性很受欢迎,因此在UICollectionView中Apple继承使用了这个特性,并且把其进行了一些扩展。使用以下方法进行注册:
-registerClass:forCellWithReuseIdentifier:
-registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
-registerNib:forCellWithReuseIdentifier:
-registerNib:forSupplementaryViewOfKind:withReuseIdentifier
相比UITableView有两个主要变化:一是加入了对某个Class的注册,这样即使不用提供nib而是用代码生成的view也可以被接受为cell了;二是不仅只是cell,Supplementary View也可以用注册的方法绑定初始化了。在对collection view的重用ID注册后,就可以像UITableView那样简单的写cell配置了:
- (UICollectionView*)collectionView:(UICollectionView*)cv cellForItemAtIndexPath:(NSIndexPath*)indexPath { MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@cell”]; // Configure the cell's content cell.imageView.image = ... return cell; }
UICollectionViewDelegate
数据无关的view的外形啊,用户交互的,由UICollectionViewDelegate来负责:
cell的高亮
cell的选中状态
可以支持长按后的菜单
关于用户交互,UICollectionView也做了改进。每个cell现在有独立的高亮事件和选中事件的delegate,用户点击cell的时候,现在会按照以下流程向delegate进行询问:
-collectionView:shouldHighlightItemAtIndexPath: 是否应该高亮?
-collectionView:didHighlightItemAtIndexPath: 如果1回答为是,那么高亮
-collectionView:shouldSelectItemAtIndexPath: 无论1结果如何,都询问是否可以被选中?
-collectionView:didUnhighlightItemAtIndexPath: 如果1回答为是,那么现在取消高亮
-collectionView:didSelectItemAtIndexPath: 如果3回答为是,那么选中cell
状态控制要比以前灵活一些,对应的高亮和选中状态分别由highlighted和selected两个属性表示。
使用UICollectionViewFlowLayout定制对象布局:
创建UICollectionViewFlowLayout布局对象.如果直接使用UICollectionViewFlowLayout布局对象来管理UICollectionView的所有单元格,那么这些单元格德大小,间距和行距都是相同的.那么可以实现非常整齐的网格效果.
但是在某些时候,UICollectionView控件中各个单元格的大小参差不齐,如果强行就爱那个这些控件缩放到统一大小,势必会影响效果.如果程序需要让UICollectionView中各控件各自显示不同的大小,则可借助于UICollectionViewDelegateFlowLayout协议来实现.该UICollectionViewDelegateFlowLayout协议继承于UICollectionViewDelegate,因此实现该协议对象可以当做UICollectionView的委托对象使用.UICollectionViewDelegateFlowLayout协议定义了如下方法:
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;该方法返回的CGSize对象将指定控制NSIndexPath对应单元格的大小.
(UIEdgeInsets)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
该方法返回UIEdgeInsets对象控制指定分区上下左右空白大小.
(CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
该方法返回的长度值将控制指定分区内最小的行间距.
(CGFloat)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
该方法返回的长度值将控制指定分区内最小的列间距.
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
该方法返回的CGSize将控制指定分区头的大小
(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
该方法返回的CGSize将控制指定分区尾部的大小单使用一下:
下面一起来简单的使用一下:
#import "ViewController.h" @interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>{ NSArray *_books; NSArray *_coversImage; } @property (weak, nonatomic) IBOutlet UICollectionView *grid; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _books=@[@"好好学习",@"好好学习",@"好好学习",@"好好学习", @"好好学习",@"好好学习",@"好好学习",@"好好学习", @"好好学习",@"好好学习",@"好好学习",@"好好学习", @"好好学习",@"好好学习",@"好好学习",@"好好学习", @"好好学习",@"好好学习",@"好好学习",@"好好学习", @"好好学习",@"好好学习",@"好好学习",@"好好学习"]; _coversImage=@[@"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png", @"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png", @"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png", @"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png", @"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png", @"jt_03.png",@"jt_03.png",@"jt_03.png",@"jt_03.png"]; self.navigationItem.title = @"学习目标"; UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init]; // 设置UICollectionView中各单元格的大小. //flowLayout.itemSize = CGSizeMake(150,150); // 设置该UICollectionView只支持水平滚动.用于设置方向 //flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; // 设置各分区上、下、左、右空白的大小。 flowLayout.sectionInset = UIEdgeInsetsMake(0, 2, 0, 0); self.grid.delegate = self; self.grid.dataSource = self; // 为UICollectionView设置布局对象 self.grid.collectionViewLayout = flowLayout; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return _books.count; } //也可以实现UICollectionViewDelegateFlowLayout代理,设置 item 大小. -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ return CGSizeMake(150,150); } // 该方法返回值决定各单元格的控件。 -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ // 为单元格定义一个静态字符串作为标示符,在使用之前一定要提前注册cell,否则会崩溃.这里是因为在storyboard中已经注册. static NSString * cellID = @"cell"; // 从可重用单元格的队列中取出一个单元格 UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath]; // 设置圆角 cell.layer.cornerRadius = 8; cell.layer.masksToBounds = YES; // 为单元格内图片控件设置图片 UIImageView *image = (UIImageView *)[cell viewWithTag:1000]; image.image = [UIImage imageNamed:_coversImage[indexPath.row]]; // 为单元格内UILabel控件设置文本 UILabel *label = (UILabel *)[cell viewWithTag:1001]; label.text = _books[indexPath.row]; cell.backgroundColor = [UIColor redColor]; return cell; }
实现效果如下:简单的网格布局界面
相关文章推荐
- UIStackView使用
- iOS9 之后的UIAlertView 的写法
- UIActivityIndicatorView的使用说明
- Ant-------默认是build.xml 改为其他的名字
- 基于MVC4+EasyUI的Web开发框架经验总结(8)--实现Office文档的预览
- UITableView常用操作
- NSOperationQueue
- 锁表参数 enque/table_size via ECC6 EHP7
- 【UER #5】万圣节的南瓜灯
- UINavigationController层次关系
- Web Service单元测试工具实例介绍之SoapUI
- The project cannot be built until build path errors are resolved解决方案
- Longest Increasing Subsequence
- hdoj 3450 Counting Sequences 【离散化 + 树状数组优化dp】
- UISwipeGestureRecognizer手势识别
- UINavigationItem UINavigationBar 关系分析
- Ligerui表格基本操作(二)
- request.getRequestURL() getRequestURI区别
- UIButton (常用点击按钮)
- 关于安装WindowBuilder问题