Подтвердить что ты не робот

UITableView prepareForSegue присваивает indexPath отправителю?

В приведенном ниже коде я просто пытаюсь настроить segue непосредственно из UIViewController в DetailViewController. Обычно я делаю segue из UITableViewCell (который, я думаю, более ясен), но на этот раз я просто хотел попробовать перейти непосредственно из ViewController, используя -tableView:didSelectRowAtIndexPath:

Мой вопрос: Я попал в ситуацию, когда мне нужно было получить доступ к UITableViewCell indexPath из -prepareForSegue:sender:. Моим решением было отправить indexPath через sender. Обычно я задавал отправителю self здесь, я огляделся и не могу найти ссылки на это, мне просто интересно, если использование отправителя для прохождения 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]];
    }
}

EDIT: Я искал в этом случае

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

по существу способ получить indexPath в -performForSegue:sender: без необходимости передавать его через параметр отправителя (в -performSegueWithIdentifier:sender:)

4b9b3361

Ответ 1

Обычно я избегаю использования отправителя в prepareForSegue:, потому что это может быть что угодно. Это позволяет утверждать, что ваш отправитель - это то, что вы ожидаете от более громоздкого и хрупкого. Кроме того, я предпочитаю проверять класс объекта destinationViewController вместо имени segue. Ваша функциональность привязана к вашему объекту (или более определенно его интерфейсу), а не к названию вашего сеанса, поэтому проверка вашего класса дает понять, что вы пытаетесь выполнить.

Ниже приведен обычный шаблон, который я использую при производстве при переходе от UITableView. Обратите внимание, что вы всегда должны проверить, включен ли destinationViewController в навигационном контроллере, а затем проверьте класс объекта, чтобы убедиться, что вы правильно его обрабатываете. Наконец, используйте assert, чтобы убедиться, что где-то вниз по линии вы не добавили какой-либо новый сегмент, который вы забыли обработать.

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // unwrap the controller if it 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.");
    }

}

Ответ 2

Вы можете использовать метод UITableView indexPathForCell. Я надеюсь, что у вас есть переменная экземпляра tableView.

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