UITableview
UITableView的两种样式
当tableview style设置为ground时,每个section的header会跟随tableview一起上下滑动;当style设置为plain时,每个section的header会悬浮在屏幕最上面,直到下一个section的header划过来,把当前的替换掉。
UITableViewStylePlain
UITableViewStyleGrouped
1.属性:
separatorStyle=UITableViewCellSelectionStyleNone; //消除分割线
2.cell:
辅助指示视图的作用是显示一个表示动作的图标,可以通过设置UITableViewCell的accessoryType来显示,默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark
还可以通过cell的accessoryView属性来自定义辅助指示视图(比如往右边放一个开关)
UITableViewCell---->selectionStyle = UITableViewCellSelectionStyleNone;//选择的时候
UITableViewCell还有一个UITableViewCellStyle属性,用于决定使用contentView的哪些子视图,以及这些子视图在contentView中的位置
Cell的重用原理
iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象
重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象
还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell,所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell
解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象
[_tableview registerNib:[UINib nibWithNibName:@"..." bundle:nil] forCellReuseIdentifier:@"cell1"];//注册 xib创建的cell
然后在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath代理方法中
通过UITableViewCell * cell=[tableView dequeueReusableCellWithIdentifier:@"cell1"] 获取 xib自定义的cell(去缓存池中查找cell);
故事板设置:
/**
* 什么时候调用:每当有一个cell进入视野范围内就会调用
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"deal"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 取出模型数据 XMGDeal *deal = self.deals[indexPath.row]; // 设置数据 UIImageView *iconView = (UIImageView *)[cell viewWithTag:10]; iconView.image = [UIImage imageNamed:deal.icon]; UILabel *titleLabel = (UILabel *)[cell viewWithTag:20]; titleLabel.text = deal.title; UILabel *priceLabel = (UILabel *)[cell viewWithTag:30]; priceLabel.text = [NSString stringWithFormat:@"¥%@", deal.price]; UILabel *buyCountLabel = (UILabel *)[cell viewWithTag:40]; buyCountLabel.text = [NSString stringWithFormat:@"%@人已购买", deal.buyCount]; return cell; }
代理方法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // 取消选中这一行 [tableView deselectRowAtIndexPath:indexPath animated:NO]; }
估算高度:
/** * 返回每一行的估计高度 * 只要返回了估计高度,那么就会先调用tableView:cellForRowAtIndexPath:方法创建cell,再调用tableView:heightForRowAtIndexPath:方法获取cell的真实高度 */ - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 200; }
进入编辑模式:
// 进入编辑模式 [self.tableView setEditing:!self.tableView.isEditing animated:YES];
#pragma mark - TableView代理方法
/**
* 只要实现这个方法,左划cell出现删除按钮的功能就有了
* 用户提交了添加(点击了添加按钮)\删除(点击了删除按钮)操作时会调用
*/
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) { // 点击了“删除”
// 删除模型
[self.deals removeObjectAtIndex:indexPath.row];
// 刷新表格
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
} else if (editingStyle == UITableViewCellEditingStyleInsert) { // 点击了+
NSLog(@"+++++ %zd", indexPath.row);
}
}
/**
* 这个方法决定了编辑模式时,每一行的编辑类型:insert(+按钮)、delete(-按钮)
*/
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row % 2 == 0? UITableViewCellEditingStyleInsert: UITableViewCellEditingStyleDelete;
}
增:
- (IBAction)add { // tableView里面需要显示新的cell数据,只需要操作模型数据 XMGDeal *deal = [[XMGDeal alloc] init]; deal.title = [NSString stringWithFormat:@"XX饭店大打折 %d折", arc4random_uniform(50)]; deal.price = [NSString stringWithFormat:@"%d", 10 + arc4random_uniform(100)]; deal.buyCount = [NSString stringWithFormat:@"%d", arc4random_uniform(1000)]; deal.icon = @"5ee372ff039073317a49af5442748071"; [self.deals insertObject:deal atIndex:0]; XMGDeal *deal2 = [[XMGDeal alloc] init]; deal2.title = [NSString stringWithFormat:@"YY饭店大打折 %d折", arc4random_uniform(50)]; deal2.price = [NSString stringWithFormat:@"%d", 10 + arc4random_uniform(100)]; deal2.buyCount = [NSString stringWithFormat:@"%d", arc4random_uniform(1000)]; deal2.icon = @"5ee372ff039073317a49af5442748071"; [self.deals insertObject:deal2 atIndex:0]; // 提醒tabelView,模型数据发生了变化,请重新识别,请重新向数据源索要数据 // [self.tableView reloadData]; // 插入某些特定的行 [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0], [NSIndexPath indexPathForRow:1 inSection:0] ] withRowAnimation:UITableViewRowAnimationLeft]; }
删:
- (IBAction)remove { // 移除模型数据 [self.deals removeObjectAtIndex:0]; [self.deals removeObjectAtIndex:0]; [self.deals removeObjectAtIndex:0]; // 刷新表格 [self.tableView reloadData]; // [self.tableView deleteRowsAtIndexPaths:@[ // [NSIndexPath indexPathForRow:0 inSection:0], // [NSIndexPath indexPathForRow:1 inSection:0], // [NSIndexPath indexPathForRow:2 inSection:0] // ] withRowAnimation:UITableViewRowAnimationRight]; }
改:
- (IBAction)update { // XMGDealCell *cell = (XMGDealCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]]; // cell.priceLabel.text = @"¥999"; // // return; // 修改模型 XMGDeal *deal = self.deals[3]; deal.price = [NSString stringWithFormat:@"%d", 50 + arc4random_uniform(100)];; // 刷新表格 [self.tableView reloadData]; // [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:0]] withRowAnimation:UITableViewRowAnimationMiddle]; }
允许在编辑模式进行多选操作:
- (void)viewDidLoad { [super viewDidLoad]; // 允许在编辑模式进行多选操作 self.tableView.allowsMultipleSelectionDuringEditing = YES; } - (IBAction)multiOperation:(id)sender { [self.tableView setEditing:!self.tableView.isEditing animated:YES]; } - (IBAction)remove { // 获得所有被选中的行 NSArray *indexPaths = [self.tableView indexPathsForSelectedRows]; // 便利所有的行号 NSMutableArray *deletedDeals = [NSMutableArray array]; for (NSIndexPath *path in indexPaths) { [deletedDeals addObject:self.deals[path.row]]; } // 删除模型数据 [self.deals removeObjectsInArray:deletedDeals]; // 刷新表格 一定要刷新数据 [self.tableView reloadData]; }