UICollectionView是一种新的数据展示方式,简单来说可以把它理解成多列的UITableView。如果你用过iBooks的话,可能你还对书架布局有一定印象,一个虚拟书架上放着你下载和购买的各类图书,整齐排列。其实这就是一个UICollectionView的表现形式,或者iPad的iOS6中的原生时钟应用中的各个时钟,也是UICollectionView的最简单的一个布局。

集合视图UICollectionView介绍

集合视图UICollectionView和表视图UITableView很相似,可根据layout属性设置,显示单元格集合内容。UICollectionViewDataSource类作为集合视图的数据源,向集合视图提供数据。集合视图依赖于委托(Delegate)中定义的方法对用户交互进行响应。 
构成集合视图的三个要素,分别为:单元格(UICollectionViewCell)、补充视图(Supplementary Views-显示额外的元数据信息)和装饰视图(Decoration Views)。

不管一个UICollectionView的布局如何变化,这三个部件都是存在的。 
为什么要使用集合视图呢?

  • 可以高度定制内容的显示;
  • 管理数据最佳的做法;
  • 可以高效处理大量数据;

集合视图单元格UICollectionViewCell

类似于表视图单元格UITableViewCell,它有一个indexPath属性定义它属于哪一个行和节点,以及其他属性定义可视化显示。有点和UITableViewCell不一样的是,UICollectionViewCell没有任何预定义的类型,我们必须手工设置单元格。

集合视图布局UICollectionViewLayout 
这个类控制单元格如何布局,如定位、透明度和层级(z-index)等等。UICollectionViewFlowLayout是UICollectionViewLayout的一个预定义的子类,用来设置按行显示的流布局(flow layout)。不过,我们可以进一步重载其属性或开发子类来定制化。

集合视图数据源UICollectionViewDataSource 
和UITableViewDataSource很像,UICollectionViewDataSource负责提供单元格给集合视图。通过UICollectionViewDataSource协议来定义,该协议提供了一些必须的方法,以及大量的可选方法。

集合视图委托UICollectionViewDelegate 
和表视图委托UITableViewDelegate很像,负责处理用户交互,通过UICollectionViewDelegate协议来定义。

创建一个简单的集合视图应用程序

我们先创建一个简单的应用集合视图的应用程序,具体看看效果。 
使用Xcode的Single View Application模板,创建一个项目,项目名称为SimpleCollectionView,类前缀为Simple。针对这个项目,我们不选择Use Storyboards,但选择Use Automatic Reference Counting复选框。

为了创建集合视图,需要让类遵守集合视图的相关协议。打开SimpleViewController.h文件,添加UICollectionViewDataSource和 UICollectionViewDelegate协议。 

#import <UIKit/UIKit.h>
@interface SimpleViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate>
@end

接着打开SimpleViewController.xib文件,从对象库中拖拉UICollectionView对象到视图中,让集合视图填充整个视图。 
然后建立UICollectionView对象到视图控制器中的输出口,如下所示: 
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;

切换回SimpleViewController.xib文件,按住Control键,点击视图中的UICollectionView对象,拖拉到File’s Owner图标上,从弹出菜单中,选择datasource。重复相同的操作,连接到delegate输出口。

这样,完成了UICollectionView对象到datasource和delegate输出口的连接。接下来,我们需要为UICollectionView准备数据。 
为了让应用程序简单一些,我们在SimpleViewController.m实现文件的附加目录(Continuation Category)添加一些私有属性,如下所示: 
#import "SimpleViewController.h"
@interface SimpleViewController ()
@property (nonatomic, strong) NSArray *dataArray;
@end

dataArray数组将存放UICollectionView所需要的数据。我们在viewDidLoad方法初始化2个数组,分别为2个section,每个包括50个NSString数据项。 
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSMutableArray *firstSection = [[NSMutableArray alloc] init];
NSMutableArray *secondSection = [[NSMutableArray alloc] init];
for (int i=0; i<50; i++){
[firstSection addObject:[NSString stringWithFormat:@"单元格 %d", i]];
[secondSection addObject:[NSString stringWithFormat:@"数据项 %d", i]];
}
self.dataArray = [[NSArray alloc] initWithObjects:firstSection, secondSection, nil];
}

创建好数据之后,接下来我们需要告诉集合视图有几部分(section),这表示我们需要实现numberOfSectionsInCollectionView:方法。 
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return [self.dataArray count];
}

在集合视图知道有几个部分之后,我们还需要告诉集合视图:每一部分(section)所包含的数据项。因此,我们需要实现collectionView: numberOfItemsInSection:方法。 
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
NSMutableArray *sectionArray = [self.dataArray objectAtIndex:section];
return [sectionArray count];
}

现在,集合视图已经知道有几个部分,并且每一部分的数据项。接下来,我们创建用于显示的单元格。

创建集合视图单元格UICollectionViewCell

表视图UITableView提供一些标准的单元格布局,但对于UICollectionView,我们需要创建自己的单元格。和表视图创建单元格一样简单,我们可以在一个独立的xib文件,或者UICollectionViewCell子类创建单元格。下面,我们会分别演示这两种方法。

使用xib文件创建集合视图单元格

创建一个新的视图文件,选择File > New > File… 菜单项,从iOS的User Interface节点下,选择View模板,新建文件命名为NibCell。

Xcode将自动打开这个文件,我们删除默认的视图(view),然后从对象库中拖拉Collection View Cell对象到画布中。

选择上述单元格视图,在Size inspector面板窗口,调整尺寸为100×100。

然后在Attributes inspector面板窗口,设置背景色为你喜欢的颜色。这里,我们设置背景色为黄色。

我们在单元格中添加一个Label标签。选中该标签,在Attributes inspector 面板窗口中,设置其Tag 属性为10。后面的代码我们用到这一属性值。

创建好xib文件后,现在我们需要关联到集合视图了。同时,我们也应用UICollectionViewLayout布局到集合视图中。回到视图控制器实现代码文件中,更新viewDidLoad方法,添加如下代码: 
UINib *cellNib = [UINib nibWithNibName:@"NibCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"simpleCell"];

上述代码获取前面创建的xib文件,并注册到集合视图中,设置可重用识别符为simpleCell,可用来出队列并实例化一个新的可供使用的单元格。

一个集合视图如果没有布局,是没有用途的。因此,我们需要创建布局。添加如下代码到viewDidLoad方法的底部。 
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(100, 100)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
flowLayout.sectionInset = UIEdgeInsetsMake(0, 2, 0, 0);

[self.collectionView setCollectionViewLayout:flowLayout];

上述代码首先创建一个UICollectionViewFlowLayout对象实例,该对象是iOS SDK内置的可供使用的流布局。该对象有很多属性可供设置,这里我们设置了3个属性:(1) item的大小,和前面我们创建的UICollectionViewCell一样大小;(2) 滚动方法;(3) 设置集合视图section之间的间隔。最后,我们将配置好的布局添加到集合视图中。

现在,我们准备好实现方法,返回集合视图所需要的单元格了,这个需要实现的就是collectionView:cellForItemAtIndexPath:方法,和tableView:cellForRowAtIndexPath:方法非常相似。在视图控制器实现文件中,添加如下方法代码: 
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSMutableArray *data = [self.dataArray objectAtIndex:indexPath.section];
NSString *cellData = [data objectAtIndex:indexPath.row];
static NSString *cellIdentifier = @"simpleCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:10];
titleLabel.text = cellData;
return cell;
}
 
上述代码,首先从dataArray数据源获取指定section的数据源,从单元格的字符串从data数组中获取指定行(row)数据。接着,创建cellIdentifier引用,要求集合视图取出一个可重用的单元格,其带有cellIdentifier标识符。如果在集合视图的缓存中存在一个可重用的单元格,将返回给我们使用,否则集合视图会在幕后为我们创建一个新的单元格对象。我们不必知道幕后的处理过程,只需了解dequeueReusableCellWithReuseIdentifier:forIndexPath:方法总是会返回一个UICollectionViewCell对象。 
我们之前在UICollectionViewCell中添加一个UILabel标签,并设置tag属性为10。这意味着我们可以检查单元格,并获取标签的引用,并转换为UILabel变量,这样才可以进一步访问UILabel属性。 
一旦UILabel属性可以访问,我们设置其text属性值,并最终返回单元格,在集合视图中显示。

运行SimpleCollectionView应用程序

现在代码编写好了,我们运行SimpleCollectionView应用程序,运行效果应该如下所示。

如上图所示,集合视图中显示了2个section的数据。

使用xib文件创建集合类单元格的更多相关文章

  1. iOS:UITableViewCell自定义单元格

    UITableViewCell:自定义的单元格,可以在xib中创建单元格,也可以在storyBorad中创建单元格.有四种创建方式 <1>在storyBorad中创建的单元格,它是静态的单 ...

  2. 自己的自定义单元格(IOS)

    定义自己的单位格有三种方法 - 代码 - xib - storyboard(推荐) 操作方法故事板 1.在TableView财产Prototype Cells至1.莫感觉1: 2.须要创建自己定义的单 ...

  3. iOS树状视图(折叠单元格)详细使用

    RATreeView是一个第三方的iOS树视图(通俗的讲就是折叠单元格),它是对UITableView的封装,定义自己的委托和数据源的法,RATreeView是高度可定制的,并且有很多功能.很多朋友都 ...

  4. iOS:集合视图UICollectionView、集合视图控制器UICollectionViewController、集合视图单元格UICollectionViewCell(创建表格的另一种控件)

    两种创建表格方式的比较:表格视图.集合视图(二者十分类似) <1>相同点:   表格视图:UITableView(位于storyboard中,通过UIViewController控制器实现 ...

  5. ExtJS 4.2 Grid组件的单元格合并

    ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能. 目录 1. 原理 2. 多列合并 3. 代码与在线演示 1. 原理 1.1 HTML代码分析 首先创建一个Grid ...

  6. C# 获取Excel中的合并单元格

    C# 获取Excel中的合并单元格 我们在制作表格时,有时经常需要合并及取消合并一些单元格.在取消合并单元格时需要逐个查找及取消,比较麻烦.这里分享一个简单的方法来识别Excel中的合并单元格,识别这 ...

  7. UITableViewCell单元格的删除、插入、移动

    UITableViewDelegate的方法      设置编辑模式中得cell的编辑样式(删除或插入)      - (UITableViewCellEditingStyle)tableView:( ...

  8. [C1] 优化 C1FlexGrid 单元格边框

    一  优化理由 如下图所示,如果按照 C1FlexGrid 自带的单元格边框设置,即对每个单元格的 CellStyle 的 BorderThickness 进行设置,会得到如下图的效果: 其中,明显可 ...

  9. [C1] C1FlexGrid 行列增删&单元格合并拆分

    上一篇中实现了 C1FlexGrid的撤销还原功能,这篇是要仿 Excel 做一个行列删除以及单元格的自由合并拆分,楼主怕在原工程里复杂的说不清道不明,所以干脆提取出来做了一个 Demo 来说明实现过 ...

随机推荐

  1. 用JQuery Validate框架,在IE8下验证报错问题解决

    网站后台用了JQuery Validate框架,版本是jQuery Validation Plugin 1.8.1 因为用的时间比较久了,一直没有更新新版本. 最近公司信息录入员有调整,没有IE11浏 ...

  2. JSP内置对象---response 响应

    将response.jsp 页面的html标签(包括html.head.body)全部删掉. <%@ page language="java" import="ja ...

  3. Oracle存储过程例子:运用了正则表达式、数组等

    代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...

  4. 近期编程问题——epoll failed:bad file descriptor

    出现问题:epoll_wait:Bad file descriptor 原因:IO时间的socket描述符在epoll_ctl处理前就关闭了. 解决方法:不要在epoll_ctl之前关闭socket描 ...

  5. kendo-ui学习笔记(一)

    1.top.jsp: <script src="<%=path%>/kendoui/js/jquery.min.js"></script> &l ...

  6. 将excel文件批量转成pdf

    防止数据编辑.改动带来的不一致性,常常要将excel文件转成pdf文件再共享.发送给对方.有时excel文件还挺多,手头上保存实在是太慢了.就考虑用VBA批量转置. 掌握几个东西,就比较容易了: 1. ...

  7. ajax+php数据增加查询获取删除

    前段代码部分其实前面已经有写出但是做一点修改所以还是贴出来,可能大家看到代码回不理解,看完图我想大家会理解我为什么这么写了,这和前端布局有关系的,先列出内容在选择内容删除或修改 <!DOCTYP ...

  8. java的数据类型转换

    java中有八种基本数据类型分别是字节型byte.整型int.短整型short.长整型long.单精度浮点型float.双精度浮点型double.字符型char.布尔型boolean.这些基本数据类型 ...

  9. Fragment的生命周期(三)

    自定义lifecycleoffragment布局文件 在main_activity布局中引用自定义的fragment布局 到logcat中查看程勋运行的结果 代码如下: 自定义的fragment布局: ...

  10. JS总结 节点

    nodeName 获取节点名称 元素节点:返回标记名称  属性节点:返回属性名称 文本节点:返回文本#text nodeTyle 获取节点类型 元素节点:返回1 属性节点:返回2 文本节点:返回3 n ...