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

nmo*_*ary 5 uitableview ios

我有一个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;
    }
Run Code Online (Sandbox Code Playgroud)

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

上面的解决方案肯定是最快速的实现,但从设计/架构的角度来看,它并不是最好的.此外,你得到了,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];
}
Run Code Online (Sandbox Code Playgroud)

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

单元格按钮标记

- (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
}
Run Code Online (Sandbox Code Playgroud)

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

按设计模式细胞

// 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` ...
}
Run Code Online (Sandbox Code Playgroud)

这是我最喜欢的解决方案.使用delegation或是blocks一个非常好的方法,你可以传递你想要的所有参数.实际上,您可能希望直接发回所需信息,而无需在以后计算.

请享用 ;)