iOS UIKit:TableView之单元格配置(2)
Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表。但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动。tableView由多个section组成,而section又由行(row)组成,也可将行称为单元格(cell)。Cell是UITableViewCell类的实例对象。
1 UITableViewCell
Table View使用UITableViewCell对象来绘制可视化的row,从而用户看到的table view其实是一个个cell对象。
1.1 Cell结构
Table view是由一行行的单元格组成,即UITableViewCell对象组成。而UITableViewCell也是一个复合结构,内部由许多部分组成的,如表 41所示是其内部主要的成员属性。
表 41 UITableViewCell主要属性
属性名 |
类型 |
描述 |
imageView |
UIImageView |
UITableViewCell有4种类型的样式,若是Basic和Subtitle类型,则会显示该属性的图像。 |
textLabel |
UILabel |
此内容为cell的标题,若要修改显示的内容,可以修改textLabel属性的text属性值。 |
contentView |
UIView |
Cell的内容视图,可以在上面添加多个子view,如可以使用UIView的addSubview方法添加子view对象。 |
backgroundView |
UIView |
整个Cell的背景视图,可以通过UITableViewCell的setBackgroundView方法修改。 |
accessoryType |
UITableViewCellAccessoryType |
Cell定义了3种附加的视图,可以指定显示的类型,默认不显示任何类型。 |
accessoryView |
UIView |
Cell定义了3种附加的视图,用户还可以自定义显示的view,即通过UITableViewCell的setAccessoryView方法修改附加视图,若自定义的内容,则忽略accessoryType属性的内容。 |
reuseIdentifier |
NSString |
可重复使用UITableViewCell对象的标识符 |
detailTextLabel |
UILabel |
如果存在附加的详细内容,则显示subtitle内容 |
editingAccessoryType |
UITableViewCellAccessoryType |
tableView进入编辑模式时,cell右边附加视图的显示样式。 |
editingAccessoryView |
UIView |
Cell定义了3种进入编辑模式时的附加视图,用户还可以自定义显示的view,即通过UITableViewCell的setEditingAccessoryView方法修改附加视图,若自定义的内容,则忽略editingAccessoryType属性的内容。 |
1.1.1 默认模型
如表 41所示,UITableViewCell对象由多个部分组成,随着不同的类型,其显示的内容也不一样,图 41是一般的显示结构。

图 41 Parts of a table view cell
1.1.2 编辑模型
当table view进入编辑模型时,UITableViewCell对象显示的内容也不一样,如图 42所示是进入编辑模型的显示内容。

图 42 Parts of a table-view cell in editing mode
1.1.3 重复使用
若在storyboard中给table view cell定义了标识符,UITableView对象将其存储在内置的队列中,使其可以重复使用该单元格。当table view向data source对象请求cell对象时,可以通过该UITableView对象的dequeueReusableCellWithIdentifier:方法获取cell对象,即在data source方法返回之前设置cell的内容和样式。从而提高table view的性能。
如下例子:首先获取storyboard中定义的table view cell,若不存在则创建一个Subtitle样式的UITableViewCell对象,接着修改单元格的内容。
- 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- 2 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
- 3 if (cell == nil) {
- 4 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"];
- 5 cell.selectionStyle = UITableViewCellSelectionStyleNone;
- 6 }
- 7 NSDictionary *item = (NSDictionary *)[self.content objectAtIndex:indexPath.row];
- 8 cell.textLabel.text = [item objectForKey:@"mainTitleKey"];
- 9 cell.detailTextLabel.text = [item objectForKey:@"secondaryTitleKey"];
- 10 NSString *path = [[NSBundle mainBundle] pathForResource:[item objectForKey:@"imageKey"] ofType:@"png"];
- 11 UIImage *theImage = [UIImage imageWithContentsOfFile:path];
- 12 cell.imageView.image = theImage;
- 13 return cell;
- 14 }
若未在storyboard中给table view cell定义标识符,并希望提高table view的性能,则也可以先通过UITableView对象的registerClass:forCellReuseIdentifier:方法注册一个cell对象。
1.2 自定义单元格
UITableViewCell预定义了4种标准类型的单元格,若仍不能满足要求,用户可以自定义cell的内容,具体说就是修改UITableViewCell对象的属性,特别是contentView和accessoryView两个属性。目前有Program和storyboard两种方式。
1.2.1 storyboard方式
1.2.1.1 Dynamic
这种方式是在storyboard中创建一个dynamic类型的table view,并修改cell的contentView的内容,从而在data source中返回storyboard中创建的UITableViewCell对象。可按如下步骤实现:
a) 在画布中,创建一个UITableView对象,并创建UITableViewCell对象,同时设置其Identifier值;
b) 选中UITableView对象,并在Attributes inspector的Content上下文中选择"Dynamic Prototypes"选项;
c) 选中UITableViewCell对象,并在Attributes inspector的Style上下文中选择"Custom"选项;
d) 选中UITableViewCell对象,并从库中拖入自定义的控件到其Content View中,可以加入一些布局约束。
e) 在data source方法中,获取UITableViewCell定义的对象,从而返回UITableViewCell对象。
1.2.1.2 Static
这方式与dynamic方式类似,其在storyboard中创建一个static类型的table view。由于static方式只能应用于库中的table view controller控件,并且无需实现data source,所以需要在Attributes inspector中指定有多少个section;然后即可在UITableViewCell的Content View中拖入喜欢的控件了。
1.2.2 Program方式
也可以通过程序的方式自定义cell,即可向UITableViewCell对象contentView属性中添加子view对象,从而实现自定义的效果,即调用contentView属性的addSubview方法添加子view对象。
如下所示往每个单元格中添加一张图片:
- 1 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- 2 {
- 3 static NSString *CellIdentifier = @"myCell";
- 4 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- 5 if(nil == cell)
- 6 {
- 7 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- 8 }
- 9 UIImage * image = [UIImage imageNamed:@"cellBackground"];
- 10 UIImageView *backView = [[UIImageView alloc] initWithImage:image];
- 11
- 12 [cell.contentView addSubview:backView];
- 13 return cell;
- 14 }
注意:
若往contentView属性中添加子view时,不应该把子view对象设置为透明状态。因为若子view为透明时,在table view滚动时将需花费比较大的资源消耗。
1.2.3 扩展附加视图
cell的附加视图也可以自定义,只需修改UITableViewCell对象的accessoryView属性即可。虽然accessoryView属性也是UIView类型,但与修改contentView属性不同,而是替换掉原来的accessoryView属性值,即直接赋值。
如下所示,将每个单元格的附加视图替换为一个label对象:
- 1 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- 2 {
- 3 UILabel * mainLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 15.0)];
- 4 mainLabel.text = @"hello";
- 5
- 6 static NSString *CellIdentifier = @"myCell";
- 7 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- 8 if(nil == cell)
- 9 {
- 10 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- 11 }
- 12
- 13 cell.accessoryView = mainLabel;
- 14 return cell;
- 15 }
2 选中管理
2.1 响应
2.1.1 基本响应
当用户点击table view的row时,那么UIKit会自动调用UITableViewDelegate对象的tableView:didSelectRowAtIndexPath:方法,从而用户可以通过实现该方法来响应用户的点击操作。同时当该方法返回后,会照常执行一些动作,如segue操作。
如下所示在用户点击时,将一个新的view controller推入Navigation栈中:
- 1 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- 2 {
- 3 [tableView deselectRowAtIndexPath:indexPath animated:NO];
- 4 BATTrailsViewController *trailsController = [[BATTrailsViewController alloc] initWithStyle:UITableViewStylePlain];
- 5 trailsController.selectedRegion = [regions objectAtIndex:indexPath.row];
- 6 [[self navigationController] pushViewController:trailsController animated:YES];
- 7 }
注意:
若row中有一个accessory view,并且为Detail或Detail Disclose类型的,则当用户点击row时将不会调用tableView:didSelectRowAtIndexPath:方法,而是调用tableView:accessoryButtonTappedForRowWithIndexPath: 方法。
2.1.2 自定义cell
当用户(软件工程师)自定义了cell的内容,并且指定了自定义控件的响应方法。那么当用户点击了cell的自定义控件,则不会响应到didSelectRowAtIndexPath方法,而是响应到控件定义的响应方法中。
如下所示,在附加view中自定义了一个UISwitch控件,并指定相应的响应方法:
- 1 - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- 2 UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@"CellWithSwitch"];
- 3 if (cell == nil) {
- 4 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellWithSwitch"];
- 5 cell.selectionStyle = UITableViewCellSelectionStyleNone;
- 6 cell.textLabel.font = [UIFont systemFontOfSize:14];
- 7 }
- 8 UISwitch *switchObj = [[UISwitch alloc] initWithFrame:CGRectMake(1.0, 1.0, 20.0, 20.0)];
- 9 switchObj.on = YES;
- 10 [switchObj addTarget:self action:@selector(toggleSoundEffects:) forControlEvents:(UIControlEventValueChanged | UIControlEventTouchDragInside)];
- 11 cell.accessoryView = switchObj;
- 12
- 13 cell.textLabel.text = @"Sound Effects";
- 14 return cell;
- 15 }
- 16
- 17 - (void)toggleSoundEffects:(id)sender {
- 18 [self.soundEffectsOn = [(UISwitch *)sender isOn];
- 19 [self reset];
- 20 }
2.2 Program选择和滚动
可以手动滚动和选择table view中的某行到一个位置(上、中和下),UITableView提供的如下三个方法:
- 1 -(void)selectRowAtIndexPath:(NSIndexPath*)indexPath
- 2 animated:(BOOL)animated
- 3 scrollPosition:(UITableViewScrollPosition)scrollPosition
- 4 - (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath
- 5 atScrollPosition:(UITableViewScrollPosition)scrollPosition
- 6 animated:(BOOL)animated
- 7 - (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition
- 8 animated:(BOOL)animated
- 9 上述三个方法参数的语义为:
- 10 indexPath:为table view行的路径为NSIndexPath类型,注意不是整数啊;
- 11 scrollPosition:为滚动的位置,有顶部、中部、底部三个位置;
- 12 animated:为是否动画滚动。
如下所示,当用户点击某行时,将当前的下一行滚动到顶部:
- 1 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- 2 {
- 3 NSIndexPath *scrollIndexPath;
- 4 scrollIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section +1];
- 5
- 6 [tableView selectRowAtIndexPath:scrollIndexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
- 7 }
3 参考文献
[1] Table View Programming Guide for IOS
iOS UIKit:TableView之单元格配置(2)的更多相关文章
- iOS tableView 静态单元格的实现
本文转自:http://home.cnblogs.com/u/wendingding/ iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一 ...
- Swift - 动态添加删除TableView的单元格(以及内部元件)
在Swift开发中,我们有时需要动态的添加或删除列表的单元格. 比如我们做一个消息提醒页面,默认页面只显示两个单元格.当点击第二个单元格(时间标签)时,下面会再添加一个单元格放置日期选择控件(同时新增 ...
- iOS UITableView 移除单元格选中时的高亮状态
在处理UITableView表格时,我们希望用户能够和触摸单元格式进行交互,但是希望用户在完成交互之后,这些单元格的选中状态能够消失,.Cocoa Touch 提供了两种方法来防止单元格背持久选中. ...
- iOS下UITableView的单元格重用逻辑
终于有时间继续UITableView的接口调用顺序这篇文章了,之前测试过,模拟器都是按照height,cellForRow这样的顺序调用接口的,iOS8以前一直是这样,但是到了iOS8,这个顺序倒过来 ...
- IOS之表视图单元格删除、移动及插入
1.实现单元格的删除,实现效果如下 - (void)viewDidLoad { [super viewDidLoad]; //设置导航栏 self.editButtonItem.title = @&q ...
- iOS中重用UITableView单元格时,千万别忘了这个
不多说,看截图
- iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建
iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建 一.实现效果 说明:该示例在storyboard中使用动态单元格来完成. 二.实现 1.项目文件结构 ...
- iOS UIKit:TableView之表格创建(1)
Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表.但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动.tableVi ...
- iOS开发UI篇—简单介绍静态单元格的使用
iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...
随机推荐
- Gartner 如何看 RASP 和 WAF?
在这个计算机网络飞速发展的网络时代里,新兴的网络威胁正在不断「侵蚀」着的应用程序和核心数据的安全,各种繁杂的防护手段也随之接踵而来.众所周知,Gartner 是全球最具权威的 IT 研究与顾问咨询公司 ...
- X86汇编快速入门
http://www.cnblogs.com/YukiJohnson/archive/2012/10/27/2741836.html
- [转贴]C++调用openssl 的AES加密例子
#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h ...
- 【Xamarin开发 Android 系列 13】 应用打包部署
原文:[Xamarin开发 Android 系列 13] 应用打包部署 开始倒叙咯................ 先更新大宝部署吧,这个章节比较的Easy,童鞋们不用费脑筋.点解?从界面上填写几个参 ...
- java实现栈的数据结构
栈是一种数据结构,只能从一端进行存储和访问.常规操作有压入栈和弹出栈. 特性:先进先出,LIFO 以下是用ArrayList为内核实现一个栈的数据结构 import java.util.ArrayLi ...
- Android Adapter的getViewTypeCount和getItemViewType
Adapter的getViewTypeCount和getItemViewType 不同的项目布局(item layout) 我们再举一个稍微复杂的例子,在上例的list中加入一些分隔线 你需要做这些: ...
- dump 验证实例恢复的起点和终点
什么时候会产生实例恢复呢?当你数据库服务器异常断电,重启数据库就会发生实例恢复.实例恢复是由数据库自动完成的,无须DBA的干涉.当然这里有个前提条件:数据文件. 在线日志文件.控制文件不得有损坏. 我 ...
- 在网页中插入CSS样式表的几种方法
1. 链入外部样式表 链入外部样式表是把样式表保存为一个样式表文件,然后在页面中用<link>标记链接到这个样式表文件,这个<link>标记必须放到页面的<head> ...
- 使用Xcode Instruments Leak解决内存泄漏问题
iOS 5.0之后apple引入了Xcode编译器特性ARC(Automatic Reference Counting,自动引用计数)来帮助开发者管理内存,但为了追求app的高性能与减少安装包大小,工 ...
- HDU-2549 壮志难酬
壮志难酬 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...