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. bug report: Jump to the invalid address stated on the next line at 0x0: ???

    gdb或者vlagrind报告: ==14569== Jump to the invalid address stated on the next line ==14569== at 0x0: ??? ...

  2. bzoj 3172 单词 ac自动机|后缀数组

    题目大意: 给定n个字符串连成了一篇文章,问每个字符串在这篇文章中出现的次数,可重复覆盖 这里ac自动机和后缀数组都可以做 当然后缀数组很容易就解决,但是相对时间消耗高 这里就只讲ac自动机了 将每个 ...

  3. reds Virtual Memory

    Virtual Memory technical specification This document details the internals of the Redis Virtual Memo ...

  4. Calculator(1.0)

    Calculator(1.0) Github链接 解题过程中遇到的困难 对于c++中类和对象的使用不够明确,看了c++的视频教程学会了用类和对象来写程序. 不会使用<queue>,在网上查 ...

  5. shell 问题解决

    如果想找常用指令,请点击图片 shell 脚本中的指令,在不确定情况下,不要随意使用nohup,否则也许会造成灾难性后果,比如--内存爆掉 shell 随机函数生成 function random() ...

  6. javascript base64 字符转换

    function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr ...

  7. SQLSERVER跨数据库操作 ---- sp_addlinkedserver

    由于项目需要跨数据库进行相应的sql操作(这里遇到的是sqlserver的A库,到sqlserver的B库) sp_addlinkedserver [ @server = ] ' server ' [ ...

  8. AngularJs的UI组件ui-Bootstrap分享(十四)——Carousel

    Carousel指令是用于图片轮播的控件,引入ngTouch模块后可以在移动端使用滑动的方式使用轮播控件. <!DOCTYPE html> <html ng-app="ui ...

  9. IIS下注册COM组件(转)

    以Excel为例 问题描述: 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005基 ...

  10. 第五章 搭建S3C6410开发板的测试环境

    在PC上可以开发Linux驱动,重新编译成ARM架构的Linux驱动模块,但最后还是要在开发板上进行测试.目前最流行的是基于三星S3C6410 ARM11架构的开发板,很多厂商在其基础上进行了扩展,开 ...