我在自定义UIButton
内部有一个UITableViewCell
,当按下该按钮时会移除该单元格。为了获取按钮所在单元格的indexPath,我调用indexPathForRowAtPoint
:在按下按钮时调用的方法如下:
-(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.
}
}
如果我按下除第一个单元格之外的任何单元格中的按钮,以及表格中是否只有一个单元格,则此方法可以正常工作。但是,如果有多个单元格并按下第一个单元格中的按钮,则会触发按钮按下并找到btnPosition,但[self.tableView indexPathForRowAtPoint:btnPosition];
会返回nil
。
例如,如果有三个单元格,每个单元格都有一个按钮:
我已经检查过tableView不是nil,正如相关但不同的帖子所建议的那样。我还确认,在btnPosition
和(x=260, y=44.009995)
时,[self.tableView indexPathForRowAtPoint:btnPosition] == nil
点都设置为相同的值[self.tableView indexPathForRowAtPoint:btnPosition] != nil
。
除了询问是否有人对这里可能发生的事情有任何想法外,我的问题是:
在什么情况下可以将相同的CGPoint传递给[self.tableView indexPathForRowAtPoint:btnPosition]
返回不同的(或无)indexPath
?
我非常感谢您提供帮助,了解我可能会在哪些方面跟踪此问题,或者听到是否有人遇到类似问题。
一些可能有帮助的补充说明(如果我提出一个问题,请原谅。请高兴地接受您的反馈意见:)
此tableView是嵌入UITableViewController
UINavigationController
的一部分
tableView有3个部分,其中2个部分在视图中隐藏(0行,没有页脚,没有标题),而我正如所描述的那样使用按钮单元格行显示该部分。
我通过以编程方式更改其水平约束来调整演示期间按钮的位置。
customUITableViewCell
,tableViewRows
和UIButton
的高度均等于60.0f
答案 0 :(得分:6)
试试这个:
修复目标选择器:
[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
}
}
答案 1 :(得分:4)
我觉得我会为此获得积分,但@ rmaddy的comment为我的代码创造了奇迹。我想把这个作为一个答案,因为我第一次错过了他的评论并花了很长时间来实施更长的修复。感谢rmaddy的修复:
作为实验,尝试使用CGPointMake(5,5)代替CGPointZero。 这有什么不同吗?
rmaddy然后explained为什么会有效:
rmaddy - 这个问题困扰了我2个星期......你修好了。非常感谢你。我可以在stackoverflow上捐赠任何积分吗?鉴于您使用的是CGRectZero以及y的事实 btnPosition的坐标是一个奇怪的值(44.009995而不是 44),我怀疑你可能有边缘案件或受害者 舍入错误。通过选择绝对值不是一个点 在视角的一角,你有更好的机会避免收尾 的问题。
答案 2 :(得分:1)
我将分享我执行此类功能的方式。如果您有一个部分,这将有效。你不需要这两行:
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.
}
对于超过1个部分,您可以执行此操作:
-(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
}
希望这会有所帮助.. :)
答案 3 :(得分:1)
将 UITapGestureRecognizer 添加到UIButton,并为GestureObject添加目标方法。
UITapGestureRecognizer *tapGestureDelete=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(callAMethod:)]; [yourDeleteButton addGestureRecognizer:tapGestureDelete];
在taget callamethod 中检索手势位置,如下所示
-(void)callAMethod:(UIGestureRecognizer *)gestureRecognizer { NSIndexPath *currentIndexPath = [self.tableView indexPathForRowAtPoint:[gestureRecognizer locationInView:self.talbleView]]; if(currentIndexPath != nil) { // remove the cell from tableview } }
我希望它会起作用......
答案 4 :(得分:0)
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
}
}