除了每个单元行左边的删除和新增图标,UITableView还支持在单元行的右侧显示一个供用户拖拉调整排序位置的控件。
不过如果要显示此控件,UITableView的数据源需要实现以下的方法。
-(void)tableView:(UITableView *)tableview moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
这样当UITableView进入编辑模式时,右侧的位置调整控件会依次询问每个单元行是否需要显示,可以实现数据源的以下方法来配置每一个单元右侧此控件的显示与否。
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
另外,如果开发者想支持排序功能,有必要在编辑模式时将诸如删除和新增的功能给屏蔽掉已达到更好的用户体验效果。
排序的新类中,对于非UITableView数据源和代理函数实现的地方,大致和HBDeleteViewController一样,只是需要改动导航栏的按钮外观而已,代码如下:
1 -(void)initUI 2 { 3 [super initUI]; 4 5 //导航栏右侧的排序按钮 6 UIButton *aOrderButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 23.0f, 15.0f)]; 7 8 [aOrderButton addTarget:self action:@selector(actBeginOrder:) forControlEvents:UIControlEventTouchUpInside]; 9 [aOrderButton setImage:[UIImage imageNamed:@"reorder"] forState:UIControlStateNormal]; 10 11 _orderItem=[[UIBarButtonItem alloc]initWithCustomView:aOrderButton]; 12 //关闭编辑模式按钮 13 _doneItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(actEndOrder:)]; 14 15 self.navigationItem.rightBarButtonItem=_orderItem; 16 } 17 18 #pragma marl- 19 #pragma mark Action 20 -(IBAction)actBeginOrder:(id)sender 21 { 22 //开启编辑模式 23 [self.tableView setEditing:YES animated:YES]; 24 self.navigationItem.rightBarButtonItem=_doneItem; 25 } 26 27 -(IBAction)actEndOrder:(id)sender 28 { 29 //关闭编辑模式 30 [self.tableView setEditing:NO animated:YES]; 31 self.navigationItem.rightBarButtonItem=_orderItem; 32 }
随后做更关键的事:数据源和代理方法的实现,代码如下:
1 #pragma mark 2 #pragma mark Table View data source 3 //setEditing:animated:后被调用 4 //询问具体Cell是不是支持编辑 5 6 -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 7 { 8 //假设需求:教练不能移动 9 if(indexPath.row == 0) 10 { 11 return NO; 12 } 13 return YES; 14 } 15 16 -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 17 { 18 return YES; 19 } 20 21 -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 22 { 23 NSMutableArray *arrNewDatasource = [NSMutableArray arrayWithArray:self.datasource]; 24 25 HBPlayerInfo *aPlayer = [self.datasource objectAtIndex:sourceIndexPath.row]; 26 27 //更新数据源 28 [arrNewDatasource removeObjectAtIndex:sourceIndexPath.row]; 29 [arrNewDatasource insertObject:aPlayer atIndex:destinationIndexPath.row]; 30 31 _datasource=[[NSArray alloc]initWithArray:arrNewDatasource]; 32 } 33 34 -(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 35 { 36 //更新UI 37 //拖动时,目的地位置的承认与否 38 //如果不承认,可以自己制作一个有效地目的地位置NSIndexPath,返回出去 39 if (proposedDestinationIndexPath.row==0) { 40 //要超过首行?不行! 41 return [NSIndexPath indexPathForRow:1 inSection:proposedDestinationIndexPath.section]; 42 } 43 return proposedDestinationIndexPath; 44 } 45 46 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 47 { 48 static NSString *CellIdentifier = @"InfoTableViewCellId"; 49 HBCustomCell *cell =(HBCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 50 51 if(cell == nil) 52 { 53 NSArray *arrNib=[[NSBundle mainBundle]loadNibNamed:@"CustomView" owner:self options:nil]; 54 if(arrNib) 55 { 56 //第一个元素就是需要的UITableViewCell 57 cell=(HBCustomCell *)[arrNib objectAtIndex:0]; 58 } 59 } 60 61 UIImage *photo = nil; 62 HBPlayerInfo *onePlayer=[self.datasource objectAtIndex:indexPath.row]; 63 if(onePlayer) 64 { 65 cell.playerName.text=onePlayer.name; 66 cell.playerName.font=[UIFont fontWithName:@"Helvetica" size:16.0f]; 67 cell.playerRole.text=onePlayer.role; 68 cell.playerRole.font=[UIFont fontWithName:@"Helvetica" size:12.0f]; 69 cell.playerNumber.text=[NSString stringWithFormat:@"No.%@",onePlayer.number]; 70 71 //插入时,更新界面的方法insertRowsAtIndexPaths会调用cellForRowAtIndexPath询问具体的UITableViewCell 72 //所以这里考虑为插入的元素准备的空头像 73 photo=[UIImage imageNamed:@"gaolin.jpeg"]; 74 if(!photo) 75 { 76 photo=[UIImage imageNamed:@"empty"]; 77 } 78 cell.playerPhoto.image=photo; 79 cell.showsReorderControl=YES; 80 } 81 return cell; 82 } 83 84 #pragma mark 85 #pragma mark TableView Delegate 86 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 87 { 88 return UITableViewCellEditingStyleNone; 89 90 /* 91 //只有编辑状态时,才有删除功能 92 //由于手指左划显示“Delete”按钮并不处于编辑状态,所以会被屏蔽掉 93 if(self.tableView.editing) 94 { 95 return UITableViewCellEditingStyleDelete; 96 } 97 return UITableViewCellEditingStyleNone; 98 */ 99 } 100 101 -(BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath 102 { 103 //进入编辑状态时单元行不向右缩进 104 return NO; 105 }
运行程序,效果如图: