Передайте NSIndexPath между UITableViews

У меня есть UITableView, показывающий данные из файла plist. Для этого табличного представления я просто сделал NSArray из содержимого plist-файла и загрузил данные в каждую ячейку. Но когда ячейка нажата, мне нужно, чтобы следующий контроллер табличного представления знал путь индекса ячейки, которая была нажата, чтобы этот контроллер представления знал, для какого элемента в массиве показывать подробности. Я пробовал следующий метод:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    staffDetailView = [[StaffDetailViewController alloc] init];
    [staffDetailView setSelectedIndexPath:indexPath];

    [self performSegueWithIdentifier:@"pushStaffDetailView" sender:self];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Выше я пытаюсь передать индексный путь выбранной ячейки объекту NSIndexPath, который я создал в новом контроллере представления.

Заголовочный файл следующего контроллера табличного представления:

@interface StaffDetailViewController : UITableViewController {

    NSIndexPath *selectedIndexPath;
    NSArray *staffArray;

}

@property (nonatomic, retain) NSIndexPath *selectedIndexPath;
@property (nonatomic, strong) NSArray *staffArray;

Здесь я определяю объект selectedIndexPath, который был установлен в предыдущем контроллере представления.

Но когда я пытаюсь получить доступ к объекту selectedIndexPath для отображения соответствующих данных, объект выглядит как nil:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    NSString *header;
    if (section == 0) {
        NSString *name = [[staffArray objectAtIndex:selectedIndexPath.row] objectForKey:@"Staff Member"];
        NSArray *splitStaffArray = [name componentsSeparatedByString:@", "];
        NSString *lastName = [splitStaffArray objectAtIndex:0];
        NSString *firstName = [splitStaffArray objectAtIndex:1];
        NSString *consolidatedName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
        NSString *assignment = [[staffArray objectAtIndex:selectedIndexPath.row] objectForKey:@"Assignment"];
        header = [NSString stringWithFormat:@"%@\n%@", consolidatedName, assignment];
        return header;
    }
    return nil;
}

Я неправильно обращаюсь к объекту selectedIndexPath? Есть ли лучший метод для передачи правильного пути индекса следующему контроллеру представления?


person The Kraken    schedule 20.02.2012    source источник
comment
Почему бы просто не переслать экземпляр объекта вместо его indexPath?   -  person Till    schedule 20.02.2012
comment
У меня есть несколько экземпляров объектов для отображения, я подумал, что для эффективности было бы лучше передать только путь индекса и позволить следующему контроллеру представления позаботиться о получении данных. Однако я попробую этот подход еще раз.   -  person The Kraken    schedule 20.02.2012
comment
При таком подходе возвращается ноль.   -  person The Kraken    schedule 20.02.2012
comment
Тогда вы сделали это неправильно - покажите нам свой альтернативный код в вопросе как дополнительную попытку решения вашей проблемы.   -  person Till    schedule 20.02.2012
comment
делайте так, как рекомендует «Тилль». передать объект по пути индекса дочернему контроллеру представления. это ненужные накладные расходы для повторной выборки из другого экземпляра массива. просто передайте то, что вам нужно.   -  person Nik Burns    schedule 20.02.2012
comment
Это имеет большое значение для памяти?   -  person The Kraken    schedule 20.02.2012
comment
будет зависеть от того, что ваш объект. попробуйте это в инструментах, но я бы подумал, что гораздо эффективнее передать объект. в противном случае вы загружаете весь массив объектов в память.   -  person Nik Burns    schedule 21.02.2012
comment
Когда я передаю отдельный объект (например, NSString) с помощью установщика, как я делал с путем индекса, он отображает нуль, когда NSLogged в следующем контроллере представления. Очень странно. Любые идеи? Я использую код, который вы видите выше.   -  person The Kraken    schedule 21.02.2012
comment
Я также согласен с @till. Вам нужно будет загрузить весь массив, а затем выполнить итерацию, что загрузит весь граф объектов вместо того, чтобы просто передать ссылку на один экземпляр.   -  person Jack Lawrence    schedule 22.02.2012
comment
Спасибо @JackLawrence. Однако, когда я пытаюсь передать отдельные объекты (например, passedName, который вы видите выше, объект имеет значение null, когда NSLogged в его контроллере представления. Есть решения?   -  person The Kraken    schedule 22.02.2012


Ответы (2)


Я пересмотрел метод didSelectRowAtIndexPath первого контроллера табличного представления:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    [self performSegueWithIdentifier:@"pushStaffDetailView" sender:self];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    [staffDetailView setSelectedIndexPath:indexPath];
    [staffDetailView setPassedName:[[staffArray objectAtIndex:indexPath.row] objectForKey:@"Staff Member"]];   

}

Казалось, что по какой-то причине мне нужно было выполнить переход перед доступом к переменным экземпляра этого контроллера представления. Странно, что я не мог просто alloc init контролер представления сам по себе. Во всяком случае, путь индекса теперь правильно передается через контроллеры представления.

person The Kraken    schedule 13.03.2012

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //I ll use NSUserDefaults to store tha indexpath. Indexpath.row is an int property, so convert to NSNumber 

    NSNumber *ip = [NSNumber numberWithInt:indexpath.row];
    NSUserDefaults *saveIP=[NSUserDefaults standartuserdefaults];
    [saveIP setObject: ip foKey:@"theIndexPath"];

    [self performSegueWithIdentifier:@"pushStaffDetailView" sender:self];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    [staffDetailView setSelectedIndexPath:indexPath];
    [staffDetailView setPassedName:[[staffArray objectAtIndex:indexPath.row] objectForKey:@"Staff Member"]];   

}

Я другой контроллер представления извлекаю сохраненный объект (данные) с кодом ниже

NSNumber *theIndexpath= [[NSUserDefaults standartuserdefaults] objectForKey:@"theIndexPath"];

Примечание. NSUserDefaults может быть плохой идеей, но это было очень просто и все еще работает для моего приложения.

person il-os    schedule 20.02.2012
comment
Это ужасный код. NSUserDefaults следует использовать только для настроек, а не для произвольных данных. Кроме того, вы ограничиваете себя одним представлением таблицы для всего приложения, поскольку используете ключи, соответствующие целым числам, которые не являются уникальными. Однако более очевидным является то, что в вашем коде есть множество орфографических ошибок, из-за которых он не сможет скомпилироваться. - person Jack Lawrence; 22.02.2012