如何跟踪表格视图单元格中按钮的索引路径?

时间:2010-05-19 08:33:29

标签: iphone cocoa-touch uitableview nsindexpath

我有一个表视图,其中每个单元格都有一个按钮附件视图。该表由提取的结果控制器管理,并经常重新排序。我希望能够按下其中一个按钮并获取该按钮的表格视图单元格的索引路径。我一直试图通过将按钮的行存储在其标记中来使这个工作好几天,但是当表重新排序时,行变得不正确并且我一直无法正确地重新排序标记。关于如何跟踪按钮的单元索引路径的任何新想法?

8 个答案:

答案 0 :(得分:31)

如果依靠button.superview感到不舒服,这种方法应该比其他一些答案更加强大:

UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];

答案 1 :(得分:25)

停止使用iOS 7 ;请查看Mike Weller's answer而不是

- (IBAction)clickedButton:(id)sender {
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell *)button.superview;
    UITableView *tableView = (UITableView *)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}

或更短:

- (IBAction)clickedButton:(id)sender {
    NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}

两者都未经测试!

答案 2 :(得分:21)

使用.superview抓取视图层次结构(就像所有现有的答案一样)是一种非常糟糕的做事方式。如果UITableViewCell的结构发生变化(之前发生过),您的应用就会中断。在代码中看到.superview.superview应该引发警钟。

应将按钮及其处理程序添加到自定义UITableViewCell子类并在那里进行布局。这就是它所属的地方。

然后,单元子类可以通过标准委托接口或块委托出按钮事件。你应该瞄准这样的事情:

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = ...;

    // ...

    cell.onButtonTapped = ^{
        [self buttonSelectedAtIndexPath:indexPath];
    }

    // OR

    cell.delegate = self;

    // ...
}

(注意:如果你进入阻止路径,你将需要使用__weak自引用来防止保留周期,但我认为这会使示例混乱。

如果您采用委托路线,那么您将使用此委托方法来实施:

- (void)cellButtonPressed:(UITableViewCell *)cell
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    // ...
}

您的代码现在可以在处理事件时完全访问相应的上下文。

在您的单元类上实现此接口应该很简单。

答案 3 :(得分:9)

我不知道为什么我需要两次调用方法superview来获取UITableViewCell。

<强>更新

感谢秋郎,现在我明白了。

&#34;那是因为SDK现在为UITableViewCell添加了一个名为UITableViewCellContentView的私有类,现在是按钮的超级视图。&#34; - 秋朗

UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];

答案 4 :(得分:6)

我也有同样的问题并构建了一个简单的递归方法,无论你触发控制的深度有多少,它都能正常工作。

-(NSIndexPath*)GetIndexPathFromSender:(id)sender{

    if(!sender) { return nil; }

    if([sender isKindOfClass:[UITableViewCell class]])
    {
        UITableViewCell *cell = sender;
        return [self.tableView indexPathForCell:cell];
    }

    return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}


-(void)ButtonClicked:(id)sender{
    NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}

答案 5 :(得分:4)

我创建了一个获取indexPath的方法,希望这对你有帮助。

在cellForRowAtIndexPath中创建按钮操作(aMethod :)

-(void) aMethod:(UIButton *)sender
{
    // Calling Magic Method which will return us indexPath.
    NSIndexPath *indexPath = [self getButtonIndexPath:sender];

    NSLog(@"IndexPath: %li", indexPath.row);
    NSLog(@"IndexRow: %li", indexPath.section);
}

//这是获取按钮的indexPath

的魔术方法
-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
    CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
    return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}

答案 6 :(得分:3)

使用这个完美的工作对我来说。

CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);

答案 7 :(得分:2)

SWIFT 2更新

以下是如何找出点击的按钮

 @IBAction func yourButton(sender: AnyObject) {


 var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(position)
    let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
    UITableViewCell
    print(indexPath?.row)
    print("Tap tap tap tap")

}