✔勾选UITableViewCell中的选定行

我是一个iOS开发新手。 选中时,我想添加一个复选标记到我的UITableViewCell 。 选中另一行时,应该删除复选标记。 我将如何做到这一点?

不要使用[tableview reloadData]; //它的一把锤子

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; } 

在你的UITableViewDatasource方法中:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil ) { cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; } if ([indexPath compare:self.lastIndexPath] == NSOrderedSame) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } return cell; } // UITableView Delegate Method -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.lastIndexPath = indexPath; [tableView reloadData]; } 

而lastIndexPath是一个property(strong) NSIndexPath* lastIndexPath;

我发现重新加载数据会中断取消animation的方式。

这个Swift实现干净地添加/删除复选标记并取消select该行:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if self.lastSelection != nil { self.myTableView.cellForRowAtIndexPath(self.lastSelection)?.accessoryType = .None } self.myTableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark self.lastSelection = indexPath self.myTableView.deselectRowAtIndexPath(indexPath, animated: true) } 

lastSelection被声明为var lastSelection: NSIndexPath!

cellForRowAtIndexPath不需要额外的活动。 在Obj-C中不应该很难复制。

设置复选标记:

 UITableViewCell *cell = ...; cell.accessoryType = UITableViewCellAccessoryCheckmark; 

要select/取消select一个单元格:

 [cell setSelected:TRUE animated:TRUE]; // select [cell setSelected:FALSE animated:TRUE]; // deselect 

要取消select以前的单元格,请使用NSIndexPath * lastSelected ivar来跟踪上次选定的单元格:

 - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { if (self.lastSelected==indexPath) return; // nothing to do // deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; old.accessoryType = UITableViewCellAccessoryNone; [old setSelected:FALSE animated:TRUE]; // select new UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; [cell setSelected:TRUE animated:TRUE]; // keep track of the last selected cell self.lastSelected = indexPath; } 

小错字

 // deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; cell.accessoryType = UITableViewCellAccessoryNone; [cell setSelected:FALSE animated:TRUE]; 

应该读

 // deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; old.accessoryType = UITableViewCellAccessoryNone; [old setSelected:FALSE animated:TRUE]; 

也在中

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == [previouslySelected intValue]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; selectedIndex = indexPath; [cell setSelected:YES animated:YES]; } else { cell.accessoryType = UITableViewCellAccessoryNone; [cell setSelected:NO animated:YES]; } } 

以前select的是你的本地伊娃等,如果你用一个选定的索引重新加载,当你轻弹通过可能的select,它也被取消select。

假设你在一个从UITableViewControllerinheritance的类中,这个在Swift 3中有效:

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Add a visual cue to indicate that the cell was selected. self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { // Invoked so we can prepare for a change in selection. // Remove previous selection, if any. if let selectedIndex = self.tableView.indexPathForSelectedRow { // Note: Programmatically deslecting does NOT invoke tableView(:didSelectRowAt:), so no risk of infinite loop. self.tableView.deselectRow(at: selectedIndex, animated: false) // Remove the visual selection indication. self.tableView.cellForRow(at: selectedIndex)?.accessoryType = .none } return indexPath } 

上面提到的代码只适用于单个select 。下面的代码肯定适用于多个select

 - (void)viewDidLoad { arrSelectionStatus =[NSMutableArray array]; //arrSelectionStatus holds the cell selection status for (int i=0; i<arrElements.count; i++) { //arrElements holds those elements which will be populated in tableview [arrSelectionStatus addObject:[NSNumber numberWithBool:NO]]; } } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell==nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } cell.textLabel.text=[arrElements objectAtIndex:indexPath.row]; if ([[arrSelectionStatus objectAtIndex:indexPath.row] boolValue] == YES) cell.accessoryType = UITableViewCellAccessoryCheckmark; else cell.accessoryType = UITableViewCellAccessoryNone; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; [arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]]; } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryNone; [arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]]; } 

只要调用didSelectRowAtIndexPath方法select任何行显示复选标记和select复选标记行隐藏复选标记。

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:true]; NSLog(@"touch"); UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryNone) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } } 

当选中的单元格(再次选中复选标记)时,只需删除select。

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { BOOL isSelected = ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark); if(isSelected){ [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; [tableView deselectRowAtIndexPath:indexPath animated:YES]; //this won't trigger the didDeselectRowAtIndexPath, but it's always a good idea to remove the selection }else{ [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } } - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; } 

奖金:

使用self.tableView.indexPathForSelectedRow检测所选单元格的indexPath

如果您重复使用大量数据的单元,上述答案不起作用。 在滚动中,您可以看到重复的选中标记。 为了避免使用下面的步骤:

  1. 声明variables:var indexNumber:NSInteger = -1

  2. 在cellforRowAtIndexPath中添加以下代码:

      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ if indexNumber == indexPath.row{ cell.accessoryType = .checkmark }else{ cell.accessoryType = .none } } 
  3. 并在didselectAtIndexpath中添加下面的代码:

重写func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath){

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark indexNumber = indexPath.row } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none }