iOS 6 开发----应用集合视图(UICollectionView)-使用xib文件创建集合视图单元格
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的数据。
未完待续!!!请看第二部分的内容!