我使用以下代码检测UITableView上的单击并根据单击的单元格以及单击单元格中的哪个元素执行操作,并对任何不匹配的元素执行默认操作。
-(void)addTapRecognizer {
// this is called when the view is created
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
singleTap.delegate = self;
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.tableView addGestureRecognizer:singleTap];
}
- (void)handleTap:(UITapGestureRecognizer *)tap {
NSLog(@"tap detected!");
if (UIGestureRecognizerStateEnded != tap.state) {
return;
}
UITableView *tableView = (UITableView *)tap.view;
CGPoint p = [tap locationInView:tap.view];
NSIndexPath* indexPath = [tableView indexPathForRowAtPoint:p];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(@"selectedIndex = %ld", (long)indexPath.row);
// take action depending where the cell was clicked
// with a default action if no element matches
MyTableViewCell *cell = (MyTableViewCell *) [self.tableView cellForRowAtIndexPath:indexPath];
CGPoint pointInCell = [tap locationInView:cell];
if(CGRectContainsPoint(cell.someImage.frame,pointInCell)) {
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
if (...) {
...
return;
}
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
我的问题是,当没有足够的单元格来填充屏幕时(例如,表格包含2个单元格,然后是下面的空白区域),当用户点击最后一个单元格下方时,这被视为单击第一个单元格(控制台在两种情况下都记录“selectedIndex = 0”)。
有没有办法区分这种点击,在表格末尾的空白区域,以及点击表格的“正确”单元格?
答案 0 :(得分:1)
有没有办法区分这种点击,在表格末尾的空白区域,以及点击"正确的"桌子的细胞?
是。对于廉价而简单的解决方案,只有在实际获得indexPath时才会执行您要执行的操作:
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:p];
if(indexPath != nil){
// do everything in here
}
基本上,您的indexPath返回nil,因为它找不到行。 From the docs:
表示与point关联的行和部分的索引路径,如果该点超出任何行的边界,则为nil。
你可以按照目前正在进行的方式进行,但是有任何理由说明你没有使用:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
这是检测用户点击的单元格的更标准方法。
如果您点击不属于某个单元格且具有许多其他好处的内容,则不会调用此方法。首先,您可以免费获得对tableView和indexPath的引用。但你也不会以这种方式需要任何手势识别器。
尝试这样的事情:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// Do stuff with cell here...
}
显然,这一切都假设您已正确设置了一个类作为表视图的委托。
注意:在使用Xcode的自动完成功能执行此操作时,很容易误写didDeselectRowAtIndexPath
而不是didSelectRowAtIndexPath
。我总是这样做,然后在20分钟后不可避免地意识到我的错误。