UITableView prepareForSegue为发件人分配indexPath?

时间:2013-03-14 15:58:24

标签: iphone objective-c cocoa-touch uitableview segue

在下面的代码中,我只是尝试直接从UIViewControllerDetailViewController设置segue。我通常从UITableViewCell(我认为更清楚)做segue,但这次我只想尝试使用ViewController直接从-tableView:didSelectRowAtIndexPath:

我的问题是:我遇到了需要从UITableViewCell indexPath内访问-prepareForSegue:sender: indexPath的情况,我的解决方案是发送{{ 1}}通过sender。通常我会将发件人设置为self,我已经环顾四周,我找不到任何对此的引用,我只是好奇如果使用sender来传递indexPath是可以接受的吗?我很确定它是,并且我确信我已经读过你可以在某个地方,但我现在找不到任何参考。

// ------------------------------------------------------------------- **
// DELEGATE: UITableView
// ------------------------------------------------------------------- **
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [self performSegueWithIdentifier:@"SEGUE_TWO" sender:indexPath];
}

// ------------------------------------------------------------------- **
// SEGUE: ViewController_ONE > DetailViewController
// ------------------------------------------------------------------- **
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    if([[segue identifier] isEqualToString:@"SEGUE_TWO"]) {
        NSUInteger cellRow = [(NSIndexPath *)sender row];
        DetailViewController *destinationController = [segue destinationViewController];
        [destinationController setDataString:[[self dataList] objectAtIndex:cellRow]];
    }
}

编辑:我在这个案例中寻找的是

NSIndexPath *indexPath = [[self tableView] indexPathForSelectedRow]; 

本质上是一种将indexPath转换为-performForSegue:sender:而无需通过sender参数传递的方法(在-performSegueWithIdentifier:sender:中)

2 个答案:

答案 0 :(得分:30)

我通常会避免在prepareForSegue:中使用发件人,因为它可能是任何。这使得断言您的发件人正在期待更加繁琐和脆弱。另外,我更喜欢检查destinationViewController对象的类而不是segue名称。您的功能与您的对象(或更具体的界面)相关联,而不是您的segue的标题,因此检查您的课程可以清楚地了解您要完成的任务。

以下是我在生产中使用的常用模板UITableView。请注意,您应始终检查destinationViewController是否嵌入到导航控制器中,然后检查对象的类以确保正确处理它。最后,使用一个断言来确保你没有添加一些你忘记处理的新segue。

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // unwrap the controller if it's embedded in the nav controller.
    UIViewController *controller;
    UIViewController *destVC = segue.destinationViewController;
    if ([destVC isKindOfClass:[UINavigationController class]]) 
    {
        UINavigationController *navController = (UINavigationController *)destVC;
        controller = [navController.viewControllers firstObject];
    } 
    else 
    {
        controller = destVC;
    }

    if ([controller isKindOfClass:[DetailViewController class]]) 
    {
        DetailViewController *vc = (DetailViewController *)controller;
        NSIndexPath *ip = [self.tableView indexPathForSelectedRow];
        [vc setDataString:[[self dataList] objectAtIndex:ip.row]];

    } 
    else 
    {
        NSAssert(NO, @"Unknown segue. All segues must be handled.");
    }

}

答案 1 :(得分:10)

您可以使用UITableView的方法indexPathForCell。我希望你有一个tableView实例变量。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([sender isKindOfClass:[UITableViewCell class]]) {
        NSIndexPath * indexPath = [self.tableView indexPathForCell:sender];
        //Your code here
    }
}