如何在tableView中使用Seque查找tapped按钮的indexPath

时间:2014-05-21 13:27:26

标签: ios uitableview

我有UITableView使用原型单元格。

单元格UIButton使用UIViewController显示Segue(模态)。

我的问题是:如何将IndexPath单元格传递给第二个视图控制器

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([segue.identifier isEqualToString:@"showGamerDetail"]) {

            //its not worked:
            NSIndexPath *indexPath = [self._tableView indexPathForSelectedRow];
            nDetailViewController *destinationViewController = segue.destinationViewController;
            destinationViewController.selectedRowTitle = [gamers objectAtIndex:indexPath.row];

        destinationViewController.indexPath = indexPath;
        destinationViewController.delegate = self;
    }

3 个答案:

答案 0 :(得分:59)

暂时忘记你正在使用故事板,让我们尝试遵循最好的方法。

你有几个解决方案,但就我而言,其中只有一个是最优的:delegation pattern

首先,您应该扩展您的单元格,并使用委托 在用户按下按钮时返回单元格。然后,您应该使用indexPathForCell获取indexPath

让我们看看方法:

单元格按钮位置

- (void)buttonClicked:(id)sender
  CGPoint buttonPosition = [sender convertPoint:CGPointZero
                                   toView:self.tableView];
  NSIndexPath *tappedIP = [self.tableView indexPathForRowAtPoint:buttonPosition];

  // When necessary 
  // UITableViewCell *clickedCell = [self.tableView cellForRowAtIndexPath:tappedIP];
}

上述解决方案肯定是实施最快的,但从设计/架构的角度来看,它不是最好的。此外,您获得indexPath,但您需要计算所有其他信息。这是一种很酷的方法,但不是最好的方法。

按钮超级视图上的单元格循环

// ContactListViewController.m

- (IBAction)emailContact:(id)sender {
    YMContact *contact = [self contactFromContactButton:sender];
    // present composer with `contact`...
}

- (YMContact *)contactFromContactButton:(UIView *)contactButton {
    UIView *aSuperview = [contactButton superview];
    while (![aSuperview isKindOfClass:[UITableViewCell class]]) {
        aSuperview = [aSuperview superview];
    }
    YMContactCell *cell = (id) aSuperview;
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    return [[self fetchedResultsController] objectAtIndexPath:indexPath];
}

以这种方式获取单元格的效果不如前者,并且它也不优雅。

单元格按钮标记

- (CustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.theLabel.text = self.theData[indexPath.row];
    cell.button.tag = indexPath.row;
    [cell.button addTarget:self action:@selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
    return cell;
}

-(void)doSomething:(UIButton *) sender {
    NSLog(@"%@",self.theData[sender.tag]);
    //sender.tag will be equal to indexPath.row
}

绝对没有。使用标签似乎是一个很酷的解决方案,但控件的标签可以用于其他原因,如下一个响应者等。我不喜欢这种方法。

按设计模式划分的单元格

// YMContactCell.h
@protocol YMContactCellDelegate
- (void)contactCellEmailWasTapped:(YMContactCell*)cell;
@end

@interface YMContactCell
@property (weak, nonatomic) id<YMContactCellDelegate> delegate;
@end

// YMContactCell.m
- (IBAction)emailContact:(id)sender {
    [self.delegate contactCellEmailWasTapped:self];
}

// ContactListViewController.m
- (void)contactCellEmailWasTapped:(YMContactCell*)cell;
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    YMContact *contact = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    // present composer with `contact` ...
}

这是我最喜欢的解决方案。 使用delegationblocks是一种非常好的方法,可以传递所需的所有参数。实际上,您可能希望直接发回所需的信息,而无需在以后计算它们。

享受;)

答案 1 :(得分:1)

非常简单的解决方案,如果你想指向所选单元格的相同segue。

- (IBAction)buttonPressed:(id)sender {

    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

    [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];

}

答案 2 :(得分:0)

首先创建一个全局int变量selecteIndex;

在您的单元格中,为您的按钮标记添加类似于单元格的indexPath.row

E.g。 btn.tag = indexPath.row;

assing&amp;点击该按钮调用操作

[btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

-(void)buttonClicked:(id)sender
{
    UIButton *btn = (UIButton*)sender;
    selectedIndex = btn.tag;
    [self performSegueWithIdentifier:@"segueName" sender:self];
}

然后在你的视图结束时写下这个函数

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"segueName"]) {
        viewController *dvc = (viewController *)[segue destinationViewController];
        [dvc setSelected:selectedIndex];
    };
}