数据源(dataSource)和代理(delegate) •UITableView需要一个数据源(dataSource)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等。没有设置数据源的UITableView只是个空壳。凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源 • •通常都要为UITableView设置代理对象(delegate),以便在UITableView触发一下事件时做出相应的处理,比如选中了某一行。凡是遵守了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象 • •通常情况下,会让控制器充当UITableView的dataSource和delegate
关于UITableView性能优化使用的提示
创建UITableViewCell时,必须设置一个唯一标示
去缓存池取出UITableViewCell时,必须传入一个标示
UITableView的编辑模式 UITableView属有个editing性,当设置为YES时,可以进入编辑模式。在编辑模式下,可以管理表格中的行,比如改变行的排列顺序、增加行、删除行,但不能修改行的内容 开启编辑模式的方法: @property(nonatomic,getter=isEditing) BOOL editing; - (void)setEditing:(BOOL)editing animated:(BOOL)animated;
在UITableView中删除或添加行 1. 开启表格的编辑模式 2. 实现UITableViewDataSource的方法: - (void)tableView:commitEditingStyle:forRowAtIndexPath: 3. 实现UITableViewDelegate的方法: - (UITableViewCellEditingStyle)tableView: editingStyleForRowAtIndexPath: 注意:如果不实现该方法,默认将编辑模式视为删除
移动UITableView的行 1. 开启表格的编辑模式 BOOL isEditing = _tableView.isEditing;
// 1. 开启表格的编辑模式
[_tableView setEditing:!isEditing animated:YES];
2. 实现UITableViewDataSource的方法: - (void)tableView:moveRowAtIndexPath:toIndexPath:
#pragma mark - 移动表格行 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { // NSLog(@"%@", _dataList); // 通过Log我们发现,在此方法中,我们只需做跟新数据的工作即可 // 界面上的动画,以及表格内容的更新,我们都不需要去处理 // 1. 取出用户选中行的数据 NSString *data = _dataList[sourceIndexPath.row]; // 2. 把用户选中的数据删除 NSLog(@"删除前的总数是 %d", _dataList.count); [_dataList removeObjectAtIndex:sourceIndexPath.row]; NSLog(@"删除后的总数是 %d", _dataList.count); // 3. 找到用户要插入行的位置,将选中行插入到数组中 [_dataList insertObject:data atIndex:destinationIndexPath.row]; NSLog(@"%@", _dataList); }
注意:只要实现了该方法,即可实现表格移动
四种刷新表格数据的方法 // 新增表格数据 [tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop]; // 删除表格数据 [tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationRight]; // 局部刷新指定的行 [tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle]; // 刷新全部表格数据,如果能够准确确定被修改的数据行,就不要用此方法 [tableView reloadData];
UITabelView常用属性
分隔线属性
separatorStyle 分隔线样式
separatorColor 分隔线颜色
选中属性
allowsSelection 允许选中
allowsMultipleSelection 允许多选
行数
indexPathsForSelectedRows 当前选中行数
indexPathsForVisibleRows 当前可见行数
背景
backgroundView 背景视图
selectedBackgroundView 选中时的背景视图
另外,UITableViewCell的selectionStyle属性可设置被选中时的背景颜色:
UITableViewCellSelectionStyleNone 没有颜色
UITableViewCellSelectionStyleBlue 蓝色(默认)
UITableViewCellSelectionStyleGray 灰色
#import "ViewController.h" @interface ViewController () // 数据数组 @property (nonatomic, strong) NSMutableArray *dataList; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 初始化数据 _dataList = [NSMutableArray arrayWithCapacity:30]; for (NSInteger i = 0; i < 30; i++) { NSString *string = [NSString stringWithFormat:@"itcast-%03d", i]; [_dataList addObject:string]; } /* 以下代码演示MyTabel类的交互 */ MyTable *myTable = [[MyTable alloc]init]; [myTable setDelegate:self]; [myTable updateData]; // [myTable setType:0]; } #pragma mark - MyTable代理方法 - (NSInteger)tellMeType:(MyTable *)myTable { return arc4random_uniform(10) % 2 == 0; } #pragma mark - 数据源方法 #pragma mark 数据行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _dataList.count; } #pragma mark 每一行显示的内容 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 1. 创建一个静态表格标示字符串,定义静态变量时,变量首字母要大写 static NSString *CellIdentifier = @"Cell"; // 2. 从缓存池查找是否有可用的表格行对象 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // 3. 如果没有找到可重用单元格对象,实例化新的单元格 if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; } NSLog(@"单元格指针(%d) %p", indexPath.row, cell); // 4. 设置单元格内容 cell.textLabel.text = _dataList[indexPath.row]; cell.detailTextLabel.text = @"详细信息"; return cell; } #pragma mark - 移动表格行 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { // NSLog(@"%@", _dataList); // 通过Log我们发现,在此方法中,我们只需做跟新数据的工作即可 // 界面上的动画,以及表格内容的更新,我们都不需要去处理 // 1. 取出用户选中行的数据 NSString *data = _dataList[sourceIndexPath.row]; // 2. 把用户选中的数据删除 NSLog(@"删除前的总数是 %d", _dataList.count); [_dataList removeObjectAtIndex:sourceIndexPath.row]; NSLog(@"删除后的总数是 %d", _dataList.count); // 3. 找到用户要插入行的位置,将选中行插入到数组中 [_dataList insertObject:data atIndex:destinationIndexPath.row]; NSLog(@"%@", _dataList); } #pragma mark 表格控件提交编辑模式 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"编辑样式 %d", editingStyle); // 判断表格是否需要删除数据 if (editingStyle == UITableViewCellEditingStyleDelete) { // 1. 删除_dataList中的数据 [_dataList removeObjectAtIndex:indexPath.row]; NSLog(@"%@", _dataList); // 2. 更新表格显示 [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight]; } else { // 1. 在_dataList中插入数据 // 可以在传入参数indexPath.row + 1 的位置插入数据 // 也就是用户当前选中行的下一行 [_dataList insertObject:@"新增数据" atIndex:(indexPath.row + 1) ]; NSLog(@"%@", _dataList); // 2. 更新表格显示 // 界面上添加数据的newPath.row应该是参数indexPath.row + 1 NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0]; [_tableView insertRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationTop]; } } #pragma mark 返回表格的编辑样式:删除、新增 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { // NSLog(@"告诉表格编辑样式"); return _tableView.tag; } #pragma mark - Actions #pragma mark 删除操作 - (IBAction)remove:(id)sender { [_tableView setTag:UITableViewCellEditingStyleDelete]; // 再次点击删除按钮,要恢复到正常浏览模式 // 编辑|浏览 // 根据表格的isEditing属性可以判断出当前是否处于编辑状态 // 如果是编辑状态,则改为浏览状态,否则,改为编辑状态 BOOL isEditing = _tableView.isEditing; // 1. 开启表格的编辑模式 [_tableView setEditing:!isEditing animated:YES]; } #pragma mark 添加操作 - (IBAction)add:(id)sender { /** 新增或者删除操作方法的执行顺序 1. 由按钮开启编辑样式 setEditing 2. 表格会对屏幕上每一个行调用 tableView:editingStyleForRowAtIndexPath: 告诉当前的行是什么编辑样式(新增或是删除) 注意:如果不实现这一方法,默认都是删除样式 3. 当用户点击屏幕上相关按钮:加好或者减号,会调用: tableView:commitEditingStyle:forRowAtIndexPath: 方法,控制器需要在此方法中更新数据,同时更新界面 */ // 利用表格的tag属性记录当前的编辑样式是新增 [_tableView setTag:UITableViewCellEditingStyleInsert]; // 判断表格当前是否是编辑模式,如果是,进入浏览状态,如果不是,进入编辑状态 BOOL isEditing = _tableView.isEditing; NSLog(@"开启编辑模式"); // 开启表格的编辑模式 [_tableView setEditing:!isEditing animated:YES]; } @end