第08章 表视图UITableView简介
2014-12-20 13:20
330 查看
UITableView表视图
UITableViewCell表视图单元
UITableViewDelegate
UITableViewDataSource
可以在UITableViewCell中添加子视图,从而在一个单元中放置更多的数据。
可以通过代码,或者在nib文件中加载他们。
两种基本样式:
分组表(grouped table):每个组都由嵌入在圆角矩形中的多个行组成。
无格式表(plain table):默认的样式,没有圆角矩形,如果使用了索引,又称为索引表。
表中的每个部分,称为数据源中的分区(section)。
分组表中,每个分组都是一个分区。
索引表中,每个索引都是一个分区。
iphone human interface guidelines中,不建议创建带有索引的分组表。
关键词
UITableView
UITableViewCell
textLabel
NSIndexPath
section
row
UITableViewDataSource
numberOfRowsInSection
cellForRowAtIndexPath
UITableViewDelegate
willSelectRowAtIndexPath
didSelectRowAtIndexPath
一个简单的表视图例子
1. 使用模板single view application创建工程
2. 向xib中拖入一个table view 实例,并关联委托和数据源到file's owner
Table View Data Source数据源方法
static NSString *simpleTableIdentifier = @"SimpleTableIdentifier";
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"HYDTableViewCell"];
获取某个分区中,有多少行
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
获取某个分区中的某行的表视图单元
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//if (cell==nil) {
// cell = [[UITableViewCell alloc]
// initWithStyle:UITableViewCellStyleDefault
// reuseIdentifier:simpleTableIdentifier];
//}
cell.textLabel.text = self.dwarves[indexPath.row];
return cell;
}
NSIndexPath:row,section
dequeueReusableCellWithIdentifier为表视图单元重新利用
当表视图单元滚离屏幕时,它们将被放置在一个可重用的单元队列中,以便后面重新利用,避免了重复创建和销毁。
如果系统运行较慢,则会清理这些单元,以释放存储空间。
添加一个图像
UIImage *image = [UIImage imageNamed:@"star.png"];
UIImage *highlightImage = [UIImage imageNamed:@"star2.png"];
cell.imageView.image = image;
cell.imageView.highlightedImage = highlightImage;
UITableViewCell属性
imageView:文本左侧的图像
textLable:文本
detailTextLable:详细文本,通常用作解释性的说明
自带样式
UITableViewCellStyleDefault:默认样式,只显示左侧图像和文本
UITableViewCellStyleSubtitle:在文本下方显示详细文本
UITableViewCellStyleValue1:在右侧显示详细文本
UITableViewCellStyleValue2:不显示图像,并将详细文本粗体显示在文本右边(居中)
以上都为数据源方法,用来向表视图提供数据。
下面介绍委托方法,来控制表示图的外观和处理用户交互
控制缩进:
-(NSInteger)tableView:(UITableView *)tableView
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
更改字体大小和行高
表视图自身有个rowHeight属性,其控制所有行的行高
而这个委托方法,可控制某行的行高
cell.textLabel.font = [UIFont systemFontOfSize:50];
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
选中:
某行将会被选中
-(NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
某行已经被选中
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
定制表示图单元:
代码方式(其实就是添加UITableViewCell子类,然后向其添加子视图)
1.通过single view application创建xcode项目Cells
2.添加新单元:创建类BIDNameAndColorCell,继承自UITableViewCell
3.为cell添加子视图
改写如下方法
- (id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//添加子视图
CGRect nameLabelRect = CGRectMake(0, 5, 70, 15);
UILabel *nameLabel = [[UILabel alloc] initWithFrame: nameLabelRect];
nameLabel.textAlignment = NSTextAlignmentRight;
nameLabel.text = @"Name:";
nameLabel.font = [UIFont systemFontOfSize:12];
[self.contentView addSubview: nameLabel];
………
}}
此时通常会遇到一个问题,cell中某些控件的值,通常是需要用户在创建出此cell后,通过cell属性来设置,
而初始化此cell的时候,这些暴露给用户的属性暂时为空的,用户还没来得及设置,
解决此问题的办法是,修改这些属性的setter,当用户设置或者修改这些属性的时候,将值重新赋给控件的某个属性。
那么此时,就需要在代码中获取某子视图的指针,以往在c++中通常是定义一个私有指针变量,来保持此变量
在oc也一样,定义一个控件的私有变量,注意,定义为私有,就会不会暴漏给外部,
此时只需要定义为实例变量即可,而不需要使用property,不过其实也可以定义为私有的outlet
类的数据成员,在类中,直接访问, _XXX
类的属性,在类中,使用self.xxx访问
如果需要在控制器类的.m中获取某子视图指针,有两种方法:
1.为此子视图定义输出口,关联xib文件中子视图实例(此种方法,外部可获取到此子视图属性)
2.为其定义私有的输出口(在.m无名类扩展中)
3.UITableView *tableView = (id)[self.view viewWithTag:1];
其实就类似与MFC,当想让外界访问到子控件时,定义成员变量,DDX/DDV
外界不需要访问此子控件,而内部又要使用的时候,采用GetDlgItem获取
关于cell 的reuse
1.提前在viewDidLoad中,通过tableView为某类型的cell,注册可重用标识符
[tableView registerClass:[BIDNameAndColorCell class]
forCellReuseIdentifier:@"HYDCELL"];
此时,以后采用dequeueReusableCellWithIdentifier所获取的cell肯定非空,不用判空。
2.采用之前的方法,不在viewDidLoad中提前注册,而是在init cell的时候,为其设置可重用标识符
static NSString *simpleTableIdentifier = @"HYDCELL";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
但是有个问题,此时传入的类型UITableViewCellStyleDefault起什么作用?所以说,如果是定制类型的cell,不应该采用此方法。
应该统一在viewDidLoad中,
采用registerClass: forCellReuseIdentifier为纯代码的Cell注册可重用标识符,
采用registerNib: forCellReuseIdentifier为xib方式的Cell注册可重用标识符
xib方式(新建UITableViewCell子类,关联,注册xib文件)
1. 创建UITableViewCell子类BIDXibCell
2. 创建XibCell.xib
3. 拖入一个Table View Cell
4. 修改关联类型为BIDXibCell,修改行高为65, 修改其可重用标识符
注意,在表视图中,还应该使用viewTable的属性rowHeight修改表视图的行高,表视图单元的行高和表视图的行高是两个概念。
而且,表视图的行高属性,修改后,则所有行统一修改。
使用委托方法,heightForRowAtIndexpath,则可修改某行的高度
5. 拖入子控件,向其关联的自定义类型中关联输出口
6. 为此xib定义的表视图单元注册可重用标识符(viewDidLoad中)
UINib *nib = [UINib nibWithNibName:@"XibCell" bundle:nil];
[self.tableView registerNib: nib forCellReuseIdentifier:@"CellTableIdentifire”];
最后,回过头来,哪种方式定义的cell比较好?
个人认为是纯代码方式,因为这种好复用,只有一个类型,不像xib方式,还得绑定一个xib文件。
分组表,多分区
使用Single View Application创建工程,Sections
向xib中拖入一个table view,格式改为grouped
将名为sortednames.plist(单词表)的文件拖入工程
@property (copy, nonatomic) NSDictionary *names; //all data
@property (copy, nonatomic) NSArray *keys; //all keys
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:SectionsTableIdentifier];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"];
self.names = [NSDictionary dictionaryWithContentsOfFile: path];
self.keys = [[self.names allKeys] sortedArrayUsingSelector: @selector(compare:)];
}
#pragma mark -
#pragma mark Table View Data Source Methods
//分区数量
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView ;
//某个分区的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section ;
//某个分区的title
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
//获取某个位置的表视图单元
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
其实创建多个分区很简单,实现响应的数据源方法即可。
索引表
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return self.keys;
}
添加索引更简单,实现以上数据源方法即可。
The returned array must have the same number of entries as you have sections, and the values must correspond to the appropriate section.
不过此数组需要跟表视图中,各分区完全匹配。
总结:
1.大量的委托方法,实现tableView的数据源和委托
2.自定义的Controller,关联一个xib,其中有一个UITableView
此时,如果要自定义Cell样式,有两种方法:
2.1.代码方式,创建UITableViewCell子类,在其init中添加子视图,
在controller中的viewDidLoad中为此cell registerClass,进而可以获取到该类型的cell
2.2.xib方式,创建一个xib,包含一个UITableViewCell, 利用IB修改界面
然后在controller中的viewDidLoad中为此cell registerNib,进而可以获取到该类型的cell
UITableViewCell表视图单元
UITableViewDelegate
UITableViewDataSource
可以在UITableViewCell中添加子视图,从而在一个单元中放置更多的数据。
可以通过代码,或者在nib文件中加载他们。
两种基本样式:
分组表(grouped table):每个组都由嵌入在圆角矩形中的多个行组成。
无格式表(plain table):默认的样式,没有圆角矩形,如果使用了索引,又称为索引表。
表中的每个部分,称为数据源中的分区(section)。
分组表中,每个分组都是一个分区。
索引表中,每个索引都是一个分区。
iphone human interface guidelines中,不建议创建带有索引的分组表。
关键词
UITableView
- (void)registerClass:([code]Class)
cellClassforCellReuseIdentifier:(
NSString *)
identifier
- (id)dequeueReusableCellWithIdentifier:([code]NSString *)
identifier
UITableViewCell
textLabel
NSIndexPath
section
row
UITableViewDataSource
numberOfRowsInSection
cellForRowAtIndexPath
UITableViewDelegate
willSelectRowAtIndexPath
didSelectRowAtIndexPath
一个简单的表视图例子
1. 使用模板single view application创建工程
2. 向xib中拖入一个table view 实例,并关联委托和数据源到file's owner
Table View Data Source数据源方法
static NSString *simpleTableIdentifier = @"SimpleTableIdentifier";
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"HYDTableViewCell"];
获取某个分区中,有多少行
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
获取某个分区中的某行的表视图单元
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//if (cell==nil) {
// cell = [[UITableViewCell alloc]
// initWithStyle:UITableViewCellStyleDefault
// reuseIdentifier:simpleTableIdentifier];
//}
cell.textLabel.text = self.dwarves[indexPath.row];
return cell;
}
NSIndexPath:row,section
dequeueReusableCellWithIdentifier为表视图单元重新利用
当表视图单元滚离屏幕时,它们将被放置在一个可重用的单元队列中,以便后面重新利用,避免了重复创建和销毁。
如果系统运行较慢,则会清理这些单元,以释放存储空间。
添加一个图像
UIImage *image = [UIImage imageNamed:@"star.png"];
UIImage *highlightImage = [UIImage imageNamed:@"star2.png"];
cell.imageView.image = image;
cell.imageView.highlightedImage = highlightImage;
UITableViewCell属性
imageView:文本左侧的图像
textLable:文本
detailTextLable:详细文本,通常用作解释性的说明
自带样式
UITableViewCellStyleDefault:默认样式,只显示左侧图像和文本
UITableViewCellStyleSubtitle:在文本下方显示详细文本
UITableViewCellStyleValue1:在右侧显示详细文本
UITableViewCellStyleValue2:不显示图像,并将详细文本粗体显示在文本右边(居中)
以上都为数据源方法,用来向表视图提供数据。
下面介绍委托方法,来控制表示图的外观和处理用户交互
控制缩进:
-(NSInteger)tableView:(UITableView *)tableView
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
更改字体大小和行高
表视图自身有个rowHeight属性,其控制所有行的行高
而这个委托方法,可控制某行的行高
cell.textLabel.font = [UIFont systemFontOfSize:50];
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
选中:
某行将会被选中
-(NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
某行已经被选中
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
定制表示图单元:
代码方式(其实就是添加UITableViewCell子类,然后向其添加子视图)
1.通过single view application创建xcode项目Cells
2.添加新单元:创建类BIDNameAndColorCell,继承自UITableViewCell
3.为cell添加子视图
改写如下方法
- (id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//添加子视图
CGRect nameLabelRect = CGRectMake(0, 5, 70, 15);
UILabel *nameLabel = [[UILabel alloc] initWithFrame: nameLabelRect];
nameLabel.textAlignment = NSTextAlignmentRight;
nameLabel.text = @"Name:";
nameLabel.font = [UIFont systemFontOfSize:12];
[self.contentView addSubview: nameLabel];
………
}}
此时通常会遇到一个问题,cell中某些控件的值,通常是需要用户在创建出此cell后,通过cell属性来设置,
而初始化此cell的时候,这些暴露给用户的属性暂时为空的,用户还没来得及设置,
解决此问题的办法是,修改这些属性的setter,当用户设置或者修改这些属性的时候,将值重新赋给控件的某个属性。
那么此时,就需要在代码中获取某子视图的指针,以往在c++中通常是定义一个私有指针变量,来保持此变量
在oc也一样,定义一个控件的私有变量,注意,定义为私有,就会不会暴漏给外部,
此时只需要定义为实例变量即可,而不需要使用property,不过其实也可以定义为私有的outlet
类的数据成员,在类中,直接访问, _XXX
类的属性,在类中,使用self.xxx访问
如果需要在控制器类的.m中获取某子视图指针,有两种方法:
1.为此子视图定义输出口,关联xib文件中子视图实例(此种方法,外部可获取到此子视图属性)
2.为其定义私有的输出口(在.m无名类扩展中)
3.UITableView *tableView = (id)[self.view viewWithTag:1];
其实就类似与MFC,当想让外界访问到子控件时,定义成员变量,DDX/DDV
外界不需要访问此子控件,而内部又要使用的时候,采用GetDlgItem获取
关于cell 的reuse
1.提前在viewDidLoad中,通过tableView为某类型的cell,注册可重用标识符
[tableView registerClass:[BIDNameAndColorCell class]
forCellReuseIdentifier:@"HYDCELL"];
此时,以后采用dequeueReusableCellWithIdentifier所获取的cell肯定非空,不用判空。
2.采用之前的方法,不在viewDidLoad中提前注册,而是在init cell的时候,为其设置可重用标识符
static NSString *simpleTableIdentifier = @"HYDCELL";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
但是有个问题,此时传入的类型UITableViewCellStyleDefault起什么作用?所以说,如果是定制类型的cell,不应该采用此方法。
应该统一在viewDidLoad中,
采用registerClass: forCellReuseIdentifier为纯代码的Cell注册可重用标识符,
采用registerNib: forCellReuseIdentifier为xib方式的Cell注册可重用标识符
xib方式(新建UITableViewCell子类,关联,注册xib文件)
1. 创建UITableViewCell子类BIDXibCell
2. 创建XibCell.xib
3. 拖入一个Table View Cell
4. 修改关联类型为BIDXibCell,修改行高为65, 修改其可重用标识符
注意,在表视图中,还应该使用viewTable的属性rowHeight修改表视图的行高,表视图单元的行高和表视图的行高是两个概念。
而且,表视图的行高属性,修改后,则所有行统一修改。
使用委托方法,heightForRowAtIndexpath,则可修改某行的高度
5. 拖入子控件,向其关联的自定义类型中关联输出口
6. 为此xib定义的表视图单元注册可重用标识符(viewDidLoad中)
UINib *nib = [UINib nibWithNibName:@"XibCell" bundle:nil];
[self.tableView registerNib: nib forCellReuseIdentifier:@"CellTableIdentifire”];
最后,回过头来,哪种方式定义的cell比较好?
个人认为是纯代码方式,因为这种好复用,只有一个类型,不像xib方式,还得绑定一个xib文件。
分组表,多分区
使用Single View Application创建工程,Sections
向xib中拖入一个table view,格式改为grouped
将名为sortednames.plist(单词表)的文件拖入工程
@property (copy, nonatomic) NSDictionary *names; //all data
@property (copy, nonatomic) NSArray *keys; //all keys
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:SectionsTableIdentifier];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"];
self.names = [NSDictionary dictionaryWithContentsOfFile: path];
self.keys = [[self.names allKeys] sortedArrayUsingSelector: @selector(compare:)];
}
#pragma mark -
#pragma mark Table View Data Source Methods
//分区数量
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView ;
//某个分区的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section ;
//某个分区的title
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
//获取某个位置的表视图单元
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
其实创建多个分区很简单,实现响应的数据源方法即可。
索引表
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return self.keys;
}
添加索引更简单,实现以上数据源方法即可。
The returned array must have the same number of entries as you have sections, and the values must correspond to the appropriate section.
不过此数组需要跟表视图中,各分区完全匹配。
总结:
1.大量的委托方法,实现tableView的数据源和委托
2.自定义的Controller,关联一个xib,其中有一个UITableView
此时,如果要自定义Cell样式,有两种方法:
2.1.代码方式,创建UITableViewCell子类,在其init中添加子视图,
在controller中的viewDidLoad中为此cell registerClass,进而可以获取到该类型的cell
2.2.xib方式,创建一个xib,包含一个UITableViewCell, 利用IB修改界面
然后在controller中的viewDidLoad中为此cell registerNib,进而可以获取到该类型的cell
相关文章推荐
- S60视图(View)架构简介
- UITableView cell自定义视图中插入Table实现复杂界面
- UITableView cell自定义视图中插入Table实现复杂界面
- IOS 表视图UITableView 束NSBundle
- 表格视图UITableView及控制器UITableViewController
- S60视图(View)结构简介
- iOS7 UITableView视图结构解析
- 创建一个简单的表视图&自定义UITableView的表单元格
- 用UITableView制作一个表格视图
- IOS UITableView表视图和导航控制器的交互使用
- UITableView中子视图非定义位置变化
- IOS学习八:UITableView表视图控件初步
- (5) iphone 开发 在表视图(UITableView) 中利用UISearchBar实现数据的搜索,视图的多功能化
- IOS之UITableView cell自定义视图中插入Tableview
- 让自定义视图拥有UISearchBar在UITableView上面自带的吸附效果
- UITableView cell自定义视图中实现复杂界面
- (2) iphone 开发 表视图UITableView结构深层剖析
- UITableView Group 样式下边框宽度并禁止滚动视图
- UitableView 之间的视图切换
- UITableView表视图控件