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

Jak*_*ake 22 iphone cocoa-touch uitableview nsindexpath

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

wxa*_*tly 31

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

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


Dou*_*aan 25

这停止了​​iOS 7的使用 ; 看看迈克·韦勒的答案,而不是

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

或更短:

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

两者都未经过测试!

  • @MikeWeller气味证实.这在iOS7中打破了.cell.superView现在返回一个`UITableViewWrapperView`而不是tableView本身. (7认同)

Mik*_*ler 21

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

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

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

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

    // ...

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

    // OR

    cell.delegate = self;

    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

您的代码现在可以在处理事件时完全访问适当的上下文.

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


Jib*_*eex 9

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

更新:

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

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

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

  • 那是因为SDK现在为UITableViewCell添加了一个名为UITableViewCellContentView的私有类,现在是按钮的超级视图. (3认同)

1km*_*ies 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];
}
Run Code Online (Sandbox Code Playgroud)


Gau*_*gla 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);
}
Run Code Online (Sandbox Code Playgroud)

// 这是获取按钮indexPath的魔术方法

-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
    CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
    return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}
Run Code Online (Sandbox Code Playgroud)