我有一个UITableViewCell
,在被轻击时会被选中。在这个选择状态下,如果用户再次点击单元格,我希望取消选中该单元格。
我找不到任何委托调用被触发。有什么实现这一功能的想法吗?是真的需要一个手势识别器吗?
我有一个UITableViewCell
,在被轻击时会被选中。在这个选择状态下,如果用户再次点击单元格,我希望取消选中该单元格。
我找不到任何委托调用被触发。有什么实现这一功能的想法吗?是真的需要一个手势识别器吗?
你可以使用委托方法 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
}
保持单选模式,但按以下方式覆盖函数:
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false {
tableView.deselectRow(at: indexPath, animated: true)
return nil
}
return indexPath
}
override func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
return nil
}
这里有一个更加简洁的解决方案:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[tableView indexPathForSelectedRow] isEqual:indexPath]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
return nil;
}
return indexPath;
}
- (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
}
}
这是伪代码。
- (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;
}
@interface XXXViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray * selectedZoneCellIndexPaths;
}
- (void)viewDidLoad
{
selectedZoneCellIndexPaths = [[NSMutableArray alloc] init];
}
- (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;
}
prisonerjohn的答案的Swift版本:
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;
}