首页 > 代码库 > 【iOS7的一些总结】9、用列表显示内容(上):列表视图UITableView

【iOS7的一些总结】9、用列表显示内容(上):列表视图UITableView

列表视图,顾名思义就是将数据的内容用列表的形式显示在屏幕上的视图。在ios中列表视图以UITableView实现,这个类在实际应用中非常的频繁,但是对于初学者来说不是非常容易理解。这里将UITableView的主要用法总结一下以备查。

UITableView定义在头文件UITableView.h中,具体的定义可以查看官方文档;从定义中可以看出,UITableView继承自UIScrollView类,因此在支持方便地显示列表数据的同时,还天生支持垂直滚动操作。组成列表的每一个元素称为UITableViewCell实例。一个UITableViewCell也是应用非常广泛的类,定义可见官方文档。在具体的使用过程中,可以创建一个独立的UITableView,也可以直接创建一个UITableViewController。这里主要记录创建UITableView的方法,下篇记录通过列表视图控制器使用UITableView。

UITableView类中定义了style属性:

@property(nonatomic, readonly) UITableViewStyle style
每一个UITableView都可以选择两种style之一,即分组模式和平面模式,这两种模式定义在枚举变量UITableViewStyle中:

typedef enum {
   UITableViewStylePlain,
   UITableViewStyleGrouped
} UITableViewStyle;

每一个列表视图的组成都是相似的,都是由一个表头视图+表体+表尾视图构成。其中表头和表尾两个视图默认为nil,需要时可以创建自定义视图添加到表头和表尾。定义如下:

@property(nonatomic, retain) UIView *tableHeaderView;
@property(nonatomic, retain) UIView *tableFooterView;
除表头和表尾之外,表体则由一串UITableViewCell(下面简称cell)构成。如果是分组表视图,则多个UITableViewCell构成一个section,每个section也有头和尾视图。

下面简单新建一个demo展示一下如何创建一个UITableView。这里假定大家都了解xcode的基本操作,所以就不再一步一步地截图了,简单叙述即可。不懂得可以去百度一下“xcode新建工程”。

新建一个single view application,在新生成的ViewController.m文件中重写loadView方法,新建一个UITableView视图。(别忘了把alloc的视图在dealloc函数中释放。)

- (void)loadView
{
    CGFloat width = [UIScreen mainScreen].bounds.size.width;
    CGFloat height = [UIScreen mainScreen].bounds.size.height;
    
    UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width,height)];
    self.view = backgroundView;
    
    _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, width, height) style:UITableViewStylePlain];
    [self.view addSubview:_tableView];
    [_tableView release];
}

编译运行,显示如下图:


表视图的协议方法——这是非常重要的部分,因为我们创建一个表视图,目的就是让视图可以显示数据,否则一个空空的表视图与废物无二。表视图所定义的协议方法由代理方法delegate和数据源方法data source方法组成。委托方法一般用于实现个性化处理表视图的基本样式(如单元格的高度等)以及捕捉单元格选中的响应;数据源方法用于完成表中的数据,如指定单元格数,以及创建每一个单元格。

要实现代理和数据源方法,首先需要让当前视图控制器支持UITableViewDelegate和UITableViewDataSource协议。做如下修改:

@interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
并且在tableView创建完成后,将tableView的delegate和dataSource设置为self,即委托给当前视图控制器来控制表视图的数据显示和响应。

_tableView.delegate = self;
_tableView.dataSource = self;

delegate和data source协议有两个方法是必须实现的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
这两个方法分别用于生成每一个cell,以及指定当前section共有多少行。实现这两个方法是想要在表视图中显示数据必须实现的最低要求。

我们在视图控制器头文件中声明一个NSArray *model(retain属性),并在viewDidLoad中将[UIFont familyNames]赋给这个属性。

在视图控制器中实现这两个代理方法:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_model count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identify = @"TableViewCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify];
    
    if (nil == cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identify];
        cell.textLabel.text = self.model[indexPath.row];
    }
    
    return cell;
}
在cellForRowAtIndexPath方法中,首先会检查是否有闲置的单元格,如果没有闲置的单元格,则会新建一个cell并将其返回。参数indexPath表示目前正在创建的单元格位于整个表视图的第几行。
编译,运行,显示结果:


如果希望实现对选中某个单元格的响应,只需要实现下面代理方法即可。在代理方法中可以实现创建新的视图控制器并控制其加载到屏幕上。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;