为什么-didDeselectRowAtIndexPath不被调用?

我创build了一个新的项目(Xcode 4,Master-Detail应用程序),以查看我是否做错了什么,但是我仍然遇到同样的问题。 我想在用户取消select一个单元格时调用-reloadData ,所以这是我的代码:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; NSLog(@"%s", __PRETTY_FUNCTION__); } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%s", __PRETTY_FUNCTION__); [tableView reloadData]; } -(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%s", __PRETTY_FUNCTION__); return indexPath; } 

问题是, didDeselectRowAtIndexPathwillDeselectRowAtIndexPath似乎并没有被调用。 这是预期的行为? tableView:didDeselectRowAtIndexPath:状态的文档

告诉委托人现在取消select指定的行。

所以我想它应该像我想的那样工作。

tableView:willDeselectRowAtIndexPath:的文档tableView:willDeselectRowAtIndexPath:也是这样说的

只有当用户试图select不同的行时存在select,才会调用此方法。 该委托被发送此方法为先前选定的行。 您可以使用UITableViewCellSelectionStyleNone来禁用触摸下单元格高亮显示。

当我使用UITableViewCellSelectionStyleNone时,它不起作用。

如果调用deselectRowAtIndexPath:animated: tableView:didDeselectRowAtIndexPath:则不会发送委托方法tableView:willDeselectRowAtIndexPath:tableView:didDeselectRowAtIndexPath: message。

我发现在IOS 5.1中有另一个怪癖 – 无论如何,如果你在表上调用reloadData ,你将不会得到任何选定行的didDeselectRowAtIndexPath 。 在我的情况下,我根据是否被选中来调整单元格布局,所以我需要在重新加载表格数据之前手动完成这个工作。

我知道这是一个老问题,但我碰到了同样的问题。

如果你使用

 [tableView reloadData] 

然后,表格数据被重新加载,并且在幕后没有select行 – 意思是

只要

 didSelectRowAtIndexPath 

被称为。 我希望这可以帮助遇到这个问题的人。

解决这个问题的一个干净的方法是做以下事情:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) // Do your cell setup work here... //If your cell should be selected... if cellShouldBeSelected { tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None) } return cell } 

这解决了一个单元格在tableView.reloadData()调用发生后没有响应被取消select的整个问题。

将该tableview的allowsMultipleSelection设置为TRUE

  self.tableView.allowsMultipleSelection = YES; 

我认为这只是简单的错误! 你为什么不使用以下内容:

 [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

而不是在该行中只使用“tableView”?
我想,很确定上面的线会给你解决scheme!
希望这有助于你,如果你回头看你的老问题!
奖励! 🙂

当第一次select任何单元格时,不调用-[UITableViewDelegate tableView:didDeselectRowAtIndexPath:]方法,但是-[UITableViewDelegate tableView:didSelectRowAtIndexPath:] 。 刚刚select了一个单元之后, didSelectRowAtIndexPath就是在didSelectRowAtIndexPath之后调用的。

还行吧。

但是如果你必须在开始时显示一个单元格(例如使用UITableViewCellAccessoryCheckmark ),那么在select另一个单元格之后,可能需要首先调用didDeselectRowAtIndexPath方法来取消select以前的单元格。

解决scheme!

您必须在-[UITableViewDataSource tableView:cellForRowAtIndexPath:]调用-[UITableView selectRowAtIndexPath:animated:scrollPosition:] -[UITableViewDataSource tableView:cellForRowAtIndexPath:]来通知已经select了一个想要的单元格。

Objective-C的

 #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; // saving the current selected row SelectedRow = indexPath.row; } - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryNone; } #pragma mark - UITableViewDataSource - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } // preventing selection style cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.text = "Some text"; if (indexPath.row == SelectedRow) { cell.accessoryType = UITableViewCellAccessoryCheckmark; // just wanted to make it selected, but it also can scroll to the selected position [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } return cell; } 

Swift 3.1

 // MARK: - UITableViewDelegate override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath)! cell.accessoryType = UITableViewCellAccessoryType.checkmark selectedRow = indexPath.row } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath)! cell.accessoryType = UITableViewCellAccessoryType.none } // MARK: - UITableViewDataSource override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell") // preventing selection style cell.selectionStyle = UITableViewCellSelectionStyle.none cell.textLabel?.text = "some text" if (indexPath.row == selectedRow) { cell.accessoryType = UITableViewCellAccessoryType.checkmark // just wanted to make it selected, but it also can scroll to the selected position tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none) } return cell }