2016-05-26 31 views
0

我使用下面的代码来检测对UITableView的点击,并根据单击哪个单元格和单元格中的哪个元素进行操作,并对任何不匹配的元素执行默认操作。如何在表格末尾添加indexPath为空格的第一个单元格的indexPath?

-(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”)。

有没有办法区分这种点击在表格末尾的空白处和单击表格的“正确”单元格之间的区别?

+1

我想知道在这种情况下'indexPath'' nil'。我不会奇怪,'nilIndexPath.row'值为0. – Larme

+0

Ooh ... spot on,我不认为nil.row会给0,indexPath是零而不是。谢谢!虽然我仍然对Gordonium的答案感兴趣,这似乎是一个更清晰的方法来做到这一点 – user14764

+1

显然,只需要检测'UITableViewCell'上的选择必须使用'tableView:didSelectRowAtIndexPath:'完成。但有些人有时想在他们身上添加多个手势,所以你的问题似乎是合法的。 – Larme

回答

1

有没有办法区分这种点击在表格末尾的空白处和点击表格的“正确”单元格之间的区别?

是的。对于廉价和简单的解决方案只能做你正在尝试,如果你真正得到的indexPath做:

NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:p]; 
if(indexPath != nil){ 
    // do everything in here 
} 

基本上,你indexPath将返回零,因为它无法找到一行。 From the docs

表示与点相关联的行和节的索引路径,如果该点超出任何行的范围,则为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分钟后不可避免地意识到我的错误。

+0

我正在使用它以便能够检测单元的哪个元素被点击。我没有找到一种方法来通过 - (无效)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath,我正在开发的应用程序(最初不是我开发的)使用这种手势识别器方法非常多。 – user14764

+0

啊。相反,您希望从您的单元中委托回调。基本上将您的表视图类设置为自定义单元类的代理。然后,在自定义单元类中,每当点击一个按钮(或类似元素)时,调用单元的委托(这是您的表视图类),然后在那里处理该调用。 – Gordonium

+0

谢谢。如Larme的评论中所建议的,检查indexPath是否为零。来自单元格的代表回调看起来更清晰,但如果我理解得很好,它需要一个自定义表视图类...所以我现在可能会坚持使用手势识别器的方式;) – user14764

相关问题