在表视图的删除操作中,每次只能够对其中一个单元进行删除,如果想要同时删除多条记录,不得不挨个地进行标准的删除操作
所以如果能够实现多选的机制,无论是删除还是其他功能的嫁接,都会变得更加方便
当UITableView进入编辑模式时,默认会将所有的单元行向右缩进。不过缩进后多出的空间是否显示系统图标以及显示哪种图标却是由开发者通过代理回调函数自己来定义。这样的话,如果我们不让它显示任何东西,而是用作显示多选中的一个选中标示的图标,多选单元行的重要思路就搞定了。
(1)新建一个继承自UITableViewCell的子类取名为MultiSelectionCell,这个类有两个成员变量:用于标记是否选中状态的图标和布尔值,并且有必要提供一个通过外部来选择或者反选当前单元行的接口。。头文件声明如下:
1 @interface HBMultiSelectionCell : UITableViewCell 2 { 3 @private 4 //是否选中状态的图标 5 UIImageView *_imgSelectionMark; 6 //是否选中状态的变量 7 BOOL _isSelected; 8 } 9 10 @property (nonatomic,assign) BOOL checked; 11 12 -(void)setChecked:(BOOL)checked;
(2)完成MultiSelectionCell的剩余代码,当被调用setEditing时,需要将一个是否选中的图标以和单元行右缩进相似的动画显示出来。反则也需要以相似的动画隐藏起来。在进入编辑状态时,单元行如果已经被选中,不仅需要在左侧显示响应的选中图标,也需要为单元行设置一个背景色来和未选中的单元行加以区分。
实现文件的代码如下:
1 @implementation HBMultiSelectionCell 2 @synthesize checked = _isSelected; 3 4 //两种情况会调用 5 //(1)Cell首次显示 6 //(2)tableview执行了setEditing:animated 7 8 -(void)setEditing:(BOOL)editing animated:(BOOL)animated 9 { 10 //和当前状态相同 11 if(self.editing == editing) 12 { 13 return; 14 } 15 16 //不要破坏原本的系统动作 17 [super setEditing:editing animated:animated]; 18 19 //进入编辑状态 20 if(editing) 21 { 22 //背景视图生成,以准备设置选中和未选中的不同背景色 23 self.backgroundView=[[UIView alloc]init]; 24 self.backgroundView.backgroundColor=[UIColor whiteColor]; 25 26 //表示选中与否的图片,位置和编辑状态的控件相同,同样放在最左边 27 //不过考虑到进入编辑状态,cel是一个从左向右的动画移动,所以初始化这个图片也放在负X位置,准备从左向右做一个动画来显示 28 if(!_imgSelectionMark) 29 { 30 _imgSelectionMark = [[UIImageView alloc]initWithFrame:CGRectMake(-14.5f, CGRectGetHeight(self.bounds)/2-14.5f, 29.0f, 29.0f)]; 31 32 _imgSelectionMark.alpha=0.0f; 33 [self addSubview:_imgSelectionMark]; 34 } 35 36 //更新选中与否的界面显示 37 [self setChecked:_isSelected]; 38 39 //从左向右的移动且显示动画 40 [UIView animateWithDuration:0.3f animations:^{ 41 _imgSelectionMark.frame=CGRectMake(6.0f, CGRectGetMinY(_imgSelectionMark.frame), CGRectGetWidth(_imgSelectionMark.frame), CGRectGetHeight(_imgSelectionMark.frame)); 42 _imgSelectionMark.alpha=1.0f; 43 }]; 44 } 45 else 46 { 47 //背景视图销毁,大家都变成普通的颜色,即默认白色 48 self.backgroundView=nil; 49 50 //文字颜色变回来 51 self.textLabel.textColor = [UIColor blackColor]; 52 self.detailTextLabel.textColor = [UIColor grayColor]; 53 54 //从右向左的移动且隐藏动画 55 [UIView animateWithDuration:0.3 animations:^{ 56 _imgSelectionMark.frame=CGRectMake(-14.5f, CGRectGetMinY(_imgSelectionMark.frame), CGRectGetWidth(_imgSelectionMark.frame), CGRectGetHeight(_imgSelectionMark.frame)); 57 _imgSelectionMark.alpha=0.0f; 58 }]; 59 } 60 } 61 62 -(void)setChecked:(BOOL)checked 63 { 64 //选中 65 if(checked) 66 { 67 //勾选的图标 68 _imgSelectionMark.image = [UIImage imageNamed:@"check.png"]; 69 //勾选状态的背景颜色 70 self.backgroundView.backgroundColor = [UIColor colorWithRed:38.0/255.0f green:96.0f/255.0f blue:211.0f/255.0f alpha:1.0]; 71 self.textLabel.textColor = [UIColor whiteColor]; 72 self.detailTextLabel.textColor = [UIColor whiteColor]; 73 } 74 //反选 75 else 76 { 77 //反选的图标 78 _imgSelectionMark.image = [UIImage imageNamed:@"uncheck.png"]; 79 self.backgroundView.backgroundColor = [UIColor whiteColor]; 80 81 self.textLabel.textColor = [UIColor blackColor]; 82 self.detailTextLabel.textColor = [UIColor grayColor]; 83 } 84 //需要记录到成员量中 85 _isSelected=checked; 86 }
(3)将MutiSelectionCell加载到表视图中
由于大部分的显示效果都和删除功能相似,所以可以新建一个继承自HBDeleteViewControll的表视图控制器取名为HBMutiSelectionViewController。在实现文件中,需要注意将删除功能规避,并且需要开启“allowsSelectionDuringEditing属性”以允许在编辑状态进行单元行选择,这样就可以在单元行选择的代理回调函数中,调用响应的MutiSelectionCell对象进行选中与否的更新和设置,代码如下:
1 -(void)initUI 2 { 3 [super initUI]; 4 5 //为了多选 6 self.tableView.allowsSelection = YES; 7 self.tableView.allowsSelectionDuringEditing = YES; 8 } 9 10 #pragma mark- 11 #pragma mark TableView data Source 12 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 13 { 14 static NSString *CellIdentifier=@"MultiTableViewCellId"; 15 HBMultiSelectionCell *cell = (HBMultiSelectionCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 16 if(cell==nil) 17 { 18 cell=[[HBMultiSelectionCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 19 } 20 21 HBPlayerInfo *onePlayer=[self.datasource objectAtIndex:indexPath.row]; 22 if(onePlayer) 23 { 24 cell.textLabel.text = onePlayer.name; 25 cell.detailTextLabel.text = onePlayer.role; 26 cell.imageView.image=[UIImage imageNamed:@"gaolin.jpeg"]; 27 28 //进入编辑状态,由于要多选,所以选择好的cell的背景颜色需要和为选择的cell的背景颜色有区别 29 //所以这里cell上的元素需要背景设置成透明(默认白色),以不影响cell选中状态时背景颜色的显示效果 30 cell.textLabel.backgroundColor = [UIColor clearColor]; 31 cell.detailTextLabel.backgroundColor = [UIColor clearColor]; 32 } 33 return cell; 34 } 35 36 #pragma mark- 37 #pragma mark Table View delegate 38 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 39 { 40 //不要显示任何编辑图标 41 return UITableViewCellEditingStyleNone; 42 } 43 44 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 45 { 46 [tableView deselectRowAtIndexPath:indexPath animated:YES]; 47 48 //编辑中状态的cell选择 49 if(self.tableView.editing) 50 { 51 if(!self.datasource || indexPath.section >= self.datasource.count) 52 { 53 return; 54 } 55 56 //更新cell的选择状态 57 HBMultiSelectionCell *cell = (HBMultiSelectionCell *)[tableView cellForRowAtIndexPath:indexPath]; 58 cell.checked= !cell.checked; 59 [cell setChecked:cell.checked]; 60 } 61 }
运行效果如图: