indexPathForRowAtPoint只返回一个uitableview中的第一个单元格

我有一个UIButton在自定义的UITableViewCell里面,按下button时删除单元格。 为了获得button所在的单元格的indexPath,我调用indexPathForRowAtPoint :在按下button时调用的方法如下:

 -(void)buttonPressed:(UIButton *)sender{ CGPoint btnPosition = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:btnPosition]; if (indexPath != nil) { //remove the cell from the tableview. } } 

这工作正常,如果我按下除第一个单元格以外的任何单元格中的button,以及如果表格中只有一个单元格时。 但是,如果有多个单元格,并按下第一个单元格中的button,触发buttonbutton,并findbtnPosition,但[self.tableView indexPathForRowAtPoint:btnPosition]; 返回nil

例如,如果有三个单元格,每个单元格都有一个button:

  1. 我按下第一个单元格button: buttonPressed被调用,但indexPath是零,所以没有任何反应。
  2. 我按下第三个单元格button: buttonPressed被调用,并按预期删除单元格。
  3. 我再次按下第一个单元格: 与之前一样,buttonPressed调用但indexPath为零。
  4. 我按下第二个单元格button: buttonPressed被调用,单元格按预期被删除。
  5. 我按下第一个单元格button: 这一次,调用buttonPressed,indexPath不是零,并按预期删除单元格。

我已经检查过,tableView并不是零,正如相关但不同的post所build议的那样。 我也已经证实,当[self.tableView indexPathForRowAtPoint:btnPosition] == nil AND [self.tableView indexPathForRowAtPoint:btnPosition] != nil时,点btnPosition被设置为相同的值(x=260, y=44.009995)

所以除了询问是否有人对这里可能发生的事情有什么看法之外,我的问题是:

在什么情况下可以传递相同的CGPoint到[self.tableView indexPathForRowAtPoint:btnPosition]返回一个不同的(或无) indexPath

如果有任何想法可以追踪这些信息,或者是否有人遇到过类似问题,我将非常感激。

一些额外的笔记,可能是有帮助的(请原谅,如果我提出一个问题,请问我会很乐意听取你的意见,以及:)

  • 这个tableView是embedded在UINavigationController中的UITableViewController一部分

  • tableView有3个部分,其中2个从视图中隐藏(0行,没有页脚,没有标题),而我介绍的部分与button单元格行描述。

  • 我正在调整演示过程中button的位置,通过编程方式更改其水平约束。

  • 我的customUITableViewCelltableViewRowsUIButton的高度都等于60.0f

试试这个:

修复目标select器:

 [button addTarget:self action:@selector(buttonPressed:event:)forControlEvents:UIControlEventTouchUpInside]; - (void)buttonPressed:(id)sender event:(id)event{ UITouch *touch = [[event allTouches] anyObject]; CGPoint touchPos = [touch locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPos]; if(indexPath != nil){ //do operation with indexPath } } 

我感到很可怕,我会得到这个点,但@ rmaddy的评论奇迹为我的代码。 我想把这个作为一个答案,因为我第一次错过了他的评论,并花了很多年执行一个更长的修复。 感谢rmaddy的修复:

作为一个实验,尝试使用CGPointMake(5,5)而不是CGPointZero。 这有什么区别?

rmaddy然后解释了为什么它的工作原理:

考虑到你使用CGRectZero和btnPosition的y坐标是一个奇怪的值(44.009995而不是44),我怀疑你可能有一个边缘案例或者是四舍五入错误的牺牲品。 通过select不在视图的绝对angular落的点,您有更好的机会避免舍入问题。

rmaddy – 这个问题一直在窃听我2个星期…而你修好了。 非常感谢你。 我可以捐赠给你的任何点stackoverflow?

UITapGestureRecognizer添加到UIButton中,并为GestureObject添加一个目标方法。

 UITapGestureRecognizer *tapGestureDelete=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(callAMethod:)]; [yourDeleteButton addGestureRecognizer:tapGestureDelete]; 

调用方法如下所示检索手势位置

 -(void)callAMethod:(UIGestureRecognizer *)gestureRecognizer { NSIndexPath *currentIndexPath = [self.tableView indexPathForRowAtPoint:[gestureRecognizer locationInView:self.talbleView]]; if(currentIndexPath != nil) { // remove the cell from tableview } } 

我希望它会工作…

我将分享我做这种types的function的方式。 这将工作,如果你有一个部分。 你不需要这两行:

 CGPoint btnPosition = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:btnPosition]; 

在添加自定义单元格的cellForRowAtIndexPath添加这些行:

 cell.btn.tag = indexPath.row; [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; 

并在buttonPressed做到这一点:

 -(void)buttonPressed:(UIButton *)sender{ UIButton *btn = (UIButton *)sender; //Remove the btn.tag number row. } 

对于多于一个部分,您可以这样做:

 -(void)buttonPressed:(UIButton *)sender{ UIButton *btn = (UIButton *)sender; UITableViewCell *cell = (UITableViewCell *)btn.superview; UITableView *tableView = (UITableView *)cell.superview; NSIndexPath *indexPath = [tableView indexPathForCell:cell]; //Remove this cell in indePath } 

希望这可以帮助 .. :)

Simalone在Swift (2.2版本)中的答案是:

 tableViewCell.button.addTarget(self, action: #selector(buttonPressed(_:event:)), forControlEvents: .TouchUpInside) ... @IBAction func buttonPressed(sender: UIButton, event: UIEvent) { if let touchPos = event.allTouches()?.first?.locationInView(self.TableView), let indexPath = self.TableView.indexPathForRowAtPoint(touchPos)?.row { // do operations with indexPath } }