UITableView点击取消select单元格

我有一个UITableViewCell被点击时select。 在这个选定状态期间,如果用户再次点击单元格,我想单元格取消select。

我无法find任何被打的代表电话。 任何想法如何实现这个? 这真的是一个手势识别器吗?

你实际上可以使用委托方法willSelectRowAtIndexPath:来做到这willSelectRowAtIndexPath:

 - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if ([cell isSelected]) { // Deselect manually. [tableView.delegate tableView:tableView willDeselectRowAtIndexPath:indexPath]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; [tableView.delegate tableView:tableView didDeselectRowAtIndexPath:indexPath]; return nil; } return indexPath; } 

请注意, deselectRowAtIndexPath:不会自动调用委托方法,因此您需要手动进行这些调用。

在Swift 4:

 func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { if let indexPathForSelectedRow = tableView.indexPathForSelectedRow, indexPathForSelectedRow == indexPath { tableView.deselectRow(at: indexPath, animated: false) return nil } return indexPath } 

这是一个更清洁的解决scheme:

 - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([[tableView indexPathForSelectedRow] isEqual:indexPath]) { [tableView deselectRowAtIndexPath:indexPath animated:YES]; return nil; } return indexPath; } 

我认为使用蓝色select颜色切换可能会给人一种奇怪的印象。 为什么不使用像复选标记的附件? 这是一个更为熟悉的select切换技术(无论是多单元还是单单元)。

有关信息,请参阅以下答案: UITableView多选

 - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if ([cell isSelected]) { // Deselect manually. if ([tableView.delegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)]) { [tableView.delegate tableView:tableView willDeselectRowAtIndexPath:indexPath]; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; if ([tableView.delegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)]) { [tableView.delegate tableView:tableView didDeselectRowAtIndexPath:indexPath]; } return nil; } return indexPath; } 

当你select一个单元格时,这个委托方法被触发。

 - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *theUITableViewCell = [tableView cellForRowAtIndexPath:path]; if (theUITableViewCell.selected == YES){ self.tableView deselectRowAtIndexPath:<#(NSIndexPath *)#> animated:<#(BOOL)#> // Do more thing }else{ // By default, it is highlighted for selected state } } 

这是伪代码。

你可以试试这个,它适用于我(单选或多选):

A.在viewDidLoad中分配一个私有的NSMutableArray,如:

 @interface XXXViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> { NSMutableArray * selectedZoneCellIndexPaths; } - (void)viewDidLoad { selectedZoneCellIndexPaths = [[NSMutableArray alloc] init]; } 

B.在UITableViewDelegate didSelectRow中添加以下几行

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { for (NSIndexPath * iter in selectedZoneCellIndexPaths) { if (indexPath.section == iter.section && indexPath.row == iter.row) { [tableView deselectRowAtIndexPath:indexPath animated:YES]; [selectedZoneCellIndexPaths removeObject:iter]; return; } } [selectedZoneCellIndexPaths addObject:indexPath]; return; } 

当使用“多选”模式时,“didSelectRowAtIndexPath”将不会被调用,当你点击一个已被选中的行。 仍然可以在“单选”模式下以编程方式select多行,这些行将触发所有点击中的didSelectRowAtIndexPath。

只要有人遇到同样的问题。

敏捷版的囚徒答案:

 public func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { let cell = tableView.cellForRowAtIndexPath(indexPath) if (cell?.selected ?? false) { // Deselect manually. tableView.delegate!.tableView?(tableView, willDeselectRowAtIndexPath: indexPath) tableView.deselectRowAtIndexPath(indexPath, animated: true) tableView.delegate!.tableView?(tableView, didDeselectRowAtIndexPath: indexPath) return nil } return indexPath; } 

从@prisonerjohn,如果有人想知道如何检查委托人是否响应@Patrick所说的select器,在Swift 3

 override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { guard let cell = tableView.cellForRow(at: indexPath) else { // Handle invalid cell ... } if cell.isSelected { if let respond = tableView.delegate?.responds( to: #selector(tableView(_:willDeselectRowAt:))), respond == true { tableView.delegate?.tableView!(tableView, willDeselectRowAt: indexPath) } tableView.deselectRow(at: indexPath, animated: true) if let respond = tableView.delegate?.responds( to: #selector(tableView(_:didDeselectRowAt:))), respond == true { tableView.delegate?.tableView!(tableView, didDeselectRowAt: indexPath) } return nil } return indexPath } 

我是在同样的事情,但@occulus的答案提供了我的提示,我失踪了。

这让我意识到完成这个任务的方法是允许在表视图中进行多项select,并在使用其中一种委托方法select新行时手动取消select之前选定的行。

在单一select模式下,表格视图试图尽可能多地select一行,这样看起来很自然,因此在select一行时不会取消select。

也许我的问题还不够具体,但是这两个答案有点宽泛。

看来这是不可能的,我走了一个单元格的手势识别器手动设置选定/未选中状态。