iOS开发之UITableView的使用

时间:2023-02-01 00:16:31

这一篇记录的是iOS开发中UITableView的使用,iOS中的UITableView跟Android中的ListView特别相似,下面用一个Demo来说明:

1、Xcode中新建工程TestSimpleTableView工程

2、在Main.storyboard中拖入一个UITableView控件

3、在ViewController.h文件中,实现UITableViewDelegate和UITableViewDataSource协议

这里需要说下的是,为了给UITableView填充数据,需要让ViewController实现这两个协议,类似于Android中给ListView填充数据,需要为ListView指定一个Adapter,然后重写Adapter中的某些方法,iOS中也是一样的,实现了上面这两个协议后,需要实现这两个协议中的某些方法,才能为UITableView添加数据。

ViewController.h文件的代码如下:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

//界面中的UITableView控件
@property (weak, nonatomic) IBOutlet UITableView *tableView;

//UITableView中的数据,用一个字符串数组来保存
@property (strong, nonatomic) NSMutableArray *tableDataArr;

@end

为了将ViewController.h中声明的tableView变量,跟Main.storyboard中的UITableView控件联系起来,需要在Main.storyboard中做一些处理,如下图所示:

iOS开发之UITableView的使用

用鼠标右键点击Main.storyboard界面中的ViewController小圆钮,然后将Outlets中的tableView拖到面板中的UITableView控件上,这样就将变量和控件建立起联系了。和Android中不同的是,要将变量和布局文件中的控件建立联系,我们是使用findViewById方法,通过控件的ID找到对应的控件。

4、下面需要在ViewController.m文件中,处理一些数据,首先需要在viewDidLoad方法里加载几条测试的数据,代码如下:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//在这里加载一些数据,用于显示在UITableView上面
[self loadData];
}

#pragma mark 加载一些数据,用于显示在UITableView上
- (void)loadData {
//初始化数组
self.tableDataArr = [NSMutableArray array];
//添加20个字符串到数组中
for(int i = 0; i < 20; i++) {
[self.tableDataArr addObject:[NSString stringWithFormat:@"table item %i", i]];
}
}
这里是直接用循环生成了20条TableView数据。

5、实现UITableViewDataSource中的两个方法:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section   和

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

代码如下:

<span style="font-size:14px;">#pragma mark 该方法返回UITableView中的item个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.tableDataArr count];
}

#pragma mark 该方法返回UITableView中每个单元格,在这里处理每个单元格中该显示什么数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//从队列中取出单元格
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
//为单元格的label设置数据
cell.textLabel.text = [self.tableDataArr objectAtIndex:indexPath.row];
return cell;
}</span>

这里的identifier是我们定义在方法外部的一个静态变量:

static NSString *identifier =@"TableViewCell";

这个变量的作用,就类似于Android中给一个ListItem设置tag,主要是为了重用TableViewCell而为单元格指定一个标识,通过这个标识就能找到单元格。

6、到这里代码基本上就写完了,但是UITableView怎么知道该从哪里获取数据呢,在Android中为ListView指定数据,需要写一个适配器Adapter,然后调用ListView的setAdapter方法指定数据,在iOS中为UITableView指定数据,可以在Main.storyboard中,鼠标右键放到UITableView上面,然后拖拉到ViewController小圆钮上面,如下图所示:

iOS开发之UITableView的使用

然后松开鼠标右键,在出现的对话框中选择dataSource,再重复一次上面的过程,选择delegate,这样就给UITableView设置了数据源和委托,委托主要用来处理UITableView的点击等事件,实现了委托中的某些方法即可处理这些事件。

除了使用上面的操作方式为UITableView指定数据源之外,还可以直接在代码中设置UITableView的数据源,可以在viewDidLoad方法中加入下面两行代码:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//在这里加载一些数据,用于显示在UITableView上面
[self loadData];
//不在Main.storyboard中设置数据源和委托的话,就用下面两行代码设置TableView的数据源和委托
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
7、如果这时候直接运行应用的话,会报错如下:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier TableViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

原因是我们没有为UITableView指定单元格,还缺少下面一步:

在Main.storyboard中拖一个TableViewCell控件到UITableView上面,如下图所示:

iOS开发之UITableView的使用

然后选中这个TableViewCell,在右侧配置这个TableViewCell的标识,如下图所示:

iOS开发之UITableView的使用

注意这里填写的identifier要跟我们定义在代码中的那个identifier一致,这样才能正确加载UITableView,再次运行应用程序后,结果如下所示:

iOS开发之UITableView的使用

这里应该是有分割线的,可能在模拟器上显示不出来,所以在上图中没有显示出分割线。

8、给每个单元格加上一个图片,这里可以通过下面的方法来给工程添加一个图片:

iOS开发之UITableView的使用
然后在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 方法中加入设置图片的代码如下所示:

#pragma mark 该方法返回UITableView中每个单元格,在这里处理每个单元格中该显示什么数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//从队列中取出单元格
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
//为单元格的label设置数据
cell.textLabel.text = [self.tableDataArr objectAtIndex:indexPath.row];
//为单元格设置一个图片
cell.imageView.image = [UIImage imageNamed:@"icon.png"];
return cell;
}
这样就可以给单元格加上图片了,效果如下图所示:

iOS开发之UITableView的使用

9、如果想给单元格加上一个侧滑删除的功能,需要实现协议中的一个方法:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

然后在这个方法中加入删除的代码如下:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableDataArr removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
加入上面的代码后即可实现侧滑删除的功能了。