UITableView Cell - 如何从按钮获取 IndexPath.row?

6

我目前在单元格中定义了一个按钮和一个跟踪其UITouchDown操作的方法,如下所示:

- (void) clickedCallSign:(id)sender {

    int index = [sender tag];
    NSLog(@"event triggered %@",index);

}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    //Callsign button
    UIButton *button;

    CGRect rect = CGRectMake(TEXT_OFFSET_X, BORDER_WIDTH, LABEL_WIDTH, LABEL_HEIGHT);
    button = [[UIButton alloc] initWithFrame:rect];
    cell.tag=[indexPath row];
    button.tag=[indexPath row];
    [button addTarget:self action:@selector(clickedCallSign:) forControlEvents:UIControlEventTouchDown];
    [button setBackgroundColor:[UIColor redColor]];
    [button setTitle:@"hello" forState:UIControlStateNormal];
    [cell.contentView addSubview:button];
    [button release];   
}

然而,当我在模拟器中点击单元格时,控制台调试信息显示:“事件触发(null)”,我的应用程序稍后就会崩溃。
我该如何正确地将indexPath.row值传递到我的clickedCallSign方法中?

查看更好的解决方案以从按下的按钮中找到indexPath: https://dev59.com/QWs05IYBdhLWcg3wAdWT#16270198 - iwasrobbed
3个回答

2
首先,index 是一个 int 类型,所以你的 NSLog 需要像这样写(注意 %d):
NSLog(@"event triggered %d", index);

(这有可能导致崩溃,但也很可能是其他原因导致不稳定。)

“%d” 的使用巧妙地获得了 indexPath.row 的值并将其传递到了 clickedCallSign 中 :) 但是应用程序仍然会崩溃..具体的堆栈跟踪信息如下: -[UIButton setText:]: unrecognized selector sent to instance 0x6877a10 2010-08-13 21:48:30.324 RF[8047:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton setText:]: unrecognized selector sent to instance 0x6877a10' - dpigera
你可能在某个地方过度释放了一些东西。你展示的代码片段中的内存管理看起来很好,因此其他地方出了问题。 - Ben Zotto
1
其实我已经在这里找到了我需要的解决方案: http://developer.apple.com/iphone/library/samplecode/Accessory/Introduction/Intro.html不过还是感谢你提供的帮助,我真的很感激。 - dpigera

2
如果您不想使用标签字段,请让按钮调用此方法:
- (void)tapAccessoryButton:(UIButton *)sender
{
    UIView *parentView = sender.superview;

    // the loop should take care of any changes in the view heirarchy, whether from
    // changes we make or apple makes.
    while (![parentView.class isSubclassOfClass:UITableViewCell.class])
        parentView = parentView.superview;

    if ([parentView.class isSubclassOfClass:UITableViewCell.class]) {
        UITableViewCell *cell = (UITableViewCell *) parentView;
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
        [self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
    }
}

2

如果您既有节又有行,标签就不再有效。尝试另一种方法来获取索引路径:

- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath {

    //...

    [button addTarget:self action:@selector(clickedCallSign:withEvent:) forControlEvents:UIControlEventTouchDown];

    //...

}

// Get the index path of the cell, where the button was pressed
- (NSIndexPath*)indexPathForEvent:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    return [self.tableView indexPathForRowAtPoint:currentTouchPosition];
}

- (IBAction)clickedCallSign:(id)sender withEvent:(UIEvent*)event
{
    NSIndexPath* buttonIndexPath = [self indexPathForEvent:event];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接