我有一个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:
不会自动调用委托方法,因此您需要手动进行这些调用。
在斯威夫特 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
}
使用“多选”模式时,单击已选中的行时不会调用“didSelectRowAtIndexPath”。在“单选”模式下,仍然可以以编程方式选择多行,并且这些行将在所有点击时触发 didSelectRowAtIndexPath。
只是提醒任何遇到同样问题的人。
这是一个更清洁的解决方案:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[tableView indexPathForSelectedRow] isEqual:indexPath]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
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
}
我认为使用蓝色选择颜色进行切换可能会给人一种奇怪的印象。为什么不使用复选标记之类的配件?这是一种更熟悉的选择切换技术(无论是多单元格还是单单元格)。
有关信息,请参阅此答案: 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;
}
当您选择一个单元格时,将触发此委托方法。
- (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;
}
来自@prisonerjohn,如果有人想知道如何检查代表是否像@Patrick 所说的那样在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
}
斯威夫特 5。
在 中UITableViewDelegate
,很简单如下:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
斯威夫特版的囚犯约翰的回答:
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;
}
我也在追求同样的事情,但@oculus 的回答为我提供了我所缺少的提示。
它使我意识到完成此操作的方法是允许在表格视图中进行多项选择,并在使用其中一种委托方法选择新行时手动取消选择先前选择的行。
在单选模式下,表格视图试图尽可能多地选择一行,因此在点击选定行时不会取消选择,这似乎很自然。
也许我的问题不够具体,但是这两个答案与我所追求的有点宽泛。
这似乎是不可能的,我使用单元格的手势识别器来手动设置选中/未选中状态。