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:
- 我按下第一个单元格button: buttonPressed被调用,但indexPath是零,所以没有任何反应。
- 我按下第三个单元格button: buttonPressed被调用,并按预期删除单元格。
- 我再次按下第一个单元格: 与之前一样,buttonPressed调用但indexPath为零。
- 我按下第二个单元格button: buttonPressed被调用,单元格按预期被删除。
- 我按下第一个单元格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的位置,通过编程方式更改其水平约束。
-
我的
customUITableViewCell
,tableViewRows
和UIButton
的高度都等于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 } }