使用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的数据。
使用xib文件创建集合类单元格的更多相关文章
- iOS:UITableViewCell自定义单元格
UITableViewCell:自定义的单元格,可以在xib中创建单元格,也可以在storyBorad中创建单元格.有四种创建方式 <1>在storyBorad中创建的单元格,它是静态的单 ...
- 自己的自定义单元格(IOS)
定义自己的单位格有三种方法 - 代码 - xib - storyboard(推荐) 操作方法故事板 1.在TableView财产Prototype Cells至1.莫感觉1: 2.须要创建自己定义的单 ...
- iOS树状视图(折叠单元格)详细使用
RATreeView是一个第三方的iOS树视图(通俗的讲就是折叠单元格),它是对UITableView的封装,定义自己的委托和数据源的法,RATreeView是高度可定制的,并且有很多功能.很多朋友都 ...
- iOS:集合视图UICollectionView、集合视图控制器UICollectionViewController、集合视图单元格UICollectionViewCell(创建表格的另一种控件)
两种创建表格方式的比较:表格视图.集合视图(二者十分类似) <1>相同点: 表格视图:UITableView(位于storyboard中,通过UIViewController控制器实现 ...
- ExtJS 4.2 Grid组件的单元格合并
ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能. 目录 1. 原理 2. 多列合并 3. 代码与在线演示 1. 原理 1.1 HTML代码分析 首先创建一个Grid ...
- C# 获取Excel中的合并单元格
C# 获取Excel中的合并单元格 我们在制作表格时,有时经常需要合并及取消合并一些单元格.在取消合并单元格时需要逐个查找及取消,比较麻烦.这里分享一个简单的方法来识别Excel中的合并单元格,识别这 ...
- UITableViewCell单元格的删除、插入、移动
UITableViewDelegate的方法 设置编辑模式中得cell的编辑样式(删除或插入) - (UITableViewCellEditingStyle)tableView:( ...
- [C1] 优化 C1FlexGrid 单元格边框
一 优化理由 如下图所示,如果按照 C1FlexGrid 自带的单元格边框设置,即对每个单元格的 CellStyle 的 BorderThickness 进行设置,会得到如下图的效果: 其中,明显可 ...
- [C1] C1FlexGrid 行列增删&单元格合并拆分
上一篇中实现了 C1FlexGrid的撤销还原功能,这篇是要仿 Excel 做一个行列删除以及单元格的自由合并拆分,楼主怕在原工程里复杂的说不清道不明,所以干脆提取出来做了一个 Demo 来说明实现过 ...
随机推荐
- 计算机网络(9)-----TCP可靠传输的实现
TCP可靠传输的实现 以字节为单位的滑动窗口 滑动窗口的滑动是以字节为单位的,发送方A和接收方B在TCP三次握手的前两次握手时协商好了发送窗口和接受窗口的大小,发送方A根据B发送来的确认连接报文中标明 ...
- SSH项目(1)
1.新建项目,添加jar包 tomcat jsp struts.hibernate.spring 2.配置 web.xml <?xml version="1.0" encod ...
- Windows环境下MongoDB的安装与配置
MongoDB是一种高性能的文档型数据库,现介绍一下在Windows环境下MongDB的安装与配置 获取MongoDB 打开官方网站 www.mongodb.org,找到页面右上解的DownLoad链 ...
- 【初级】linux mv 命令详解及使用方法实战
mv:移动文件或者将文件改名 前言: mv是move的缩写,顾名思义是移动.它的功能既能移动文件/文件夹,又可以用来改名,经常用来做文件的备份,比如再删除之前,先给文件做备份(保护数据)也是linux ...
- XCode修改公司名称和作者名称
新建的文件最上方都会有一段类似如下的版权声明 // // ViewController.m // CBDemoProject001 // // Created by CB on 16/3/17. ...
- I/O Directory类
Directory类 Directory类位于System.IO 命名空间.Directory类提供了在目录和子目录中进行创建移动和列举操作的静态方法.此外,你还可以访问和操作各种各样的目录属性. 1 ...
- Java特性-Collection和Map
创建博客的目的主要帮助自己记忆和复习日常学到和用到的知识:或有纰漏请大家斧正,非常感谢! 之前面试,被问过一个问题:List和Set的区别. 主要区别很明显了,两者都是数组形式存在的,继承了Colle ...
- Javascript跨域
跨域:只要协议.域名或端口有任何一个不同,就定义为跨域. CORS(Cross-Origin Resource Sharing):即跨域资源共享.定义了在访问跨域资源时,浏览器和服务器该如何沟通.CO ...
- 清除mysql表中数据
delete from 表名; truncate table 表名; 不带where参数的delete语句可以删除mysql表中所有内容,使用truncate table也可以清空mysql表中所有内 ...
- java第一天学习作业及答案
作业一 一.选择题 1.选出在java中有效的注释声明(AD)(选两项) A.//这是注释 B.*/这是注释*/ C./这是注释 D./*这是注释*/ 2.在控制台运行一个java程序,使用的命名正确 ...