1

Я выполнял несколько руководств и вопросов по переполнению стека, но не получал желаемого результата при редактировании основного вида таблицы.Редактирование ячейки TableView с помощью didSelectRowAtIndexPath с использованием данных ядра

У меня есть приложение, которое является контроллером табличного представления. Если я нажму кнопку «плюс», это приведет к модификации контроллера вида, позволяющего добавлять информацию в 4 текстовых поля (и один выбор даты). Когда я сохраняю его, он сохраняет данные ядра, а в представлении таблицы отображается информация. Я хочу, чтобы теперь просто можно было нажимать на ячейку в представлении таблицы, быть принятым на другой контроллер представления и, если нужно, редактировать ячейки. Этот контроллер выглядит так же, как и контроллер добавления.

В настоящее время в подробном представлении он не показывает мне значения в текстовом поле, а NSLog возвращается NULL.

В табличном, я использую NSFetchedResultsController для заполнения информации в базе данных и NSManagedContext как следует из App делегата:

- (NSManagedObjectContext *)managedObjectContext 
{ 
    NSManagedObjectContext *context = nil; 
    id delegate = [[UIApplication sharedApplication] delegate]; 
    if ([delegate performSelector:@selector(managedObjectContext)]) 
    { 
     context = [delegate managedObjectContext]; 
    } 
    return context; 
} 

- (NSFetchedResultsController *)fetchedResultsController 
{ 
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; 

    if (_fetchedResultsController != nil) 
    { 
     return _fetchedResultsController; 
    } 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Information" inManagedObjectContext:managedObjectContext]; 
    fetchRequest.entity = entity; 
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"date.historyDate" ascending:NO]; 
    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort]; 
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"date.historyDate" cacheName:nil]; 
    self.fetchedResultsController = theFetchedResultsController; 
    _fetchedResultsController.delegate = self; 
    return _fetchedResultsController; 
} 

CellforRow =

cell.textLabel.text = information.vendor; 
cell.detailTextLabel.text = information.type; 

Мой didSelectRowAtIndexPath способ заключается в следующем:

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

    DetailViewController *detailViewController = [[DetailViewController alloc] init]; 
    Information *selectedInformation = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    detailViewController.selectedInformation = selectedInformation;  
    [self.navigationController pushViewController:detailViewController animated:YES]; 
} 

D D etailViewController имеет свойство для информации:

@property (nonatomic, strong) Information *selectedInformation; 

viewDidLoad в деталях выглядит следующим образом:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.title = self.selectedInformation.vendor; 
    self.editingNameField.text = self.selectedInformation.vendor; 

    NSLog(@"%@", self.editingNameField.text); 
} 

EDIT: Обновление включает prepareForSegue

NSIndexPath *indexPath = [self.timelineTableView indexPathForCell:sender]; 
Information *selectedInformation = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
if ([segue.identifier isEqualToString:@"Editable Cell"]) 
{ 
    DetailViewController *selectedInformationTVC = [segue destinationViewController]; 

    [selectedInformationTVC setSelectedInformation:selectedInformation]; 
} 

Что вызывает setSelectedInformation : - (void) setSelectedИнформация: (информация *) selectedИнформация { self.title = self.selectedInformation.vendor;

self.editingNameField.text = self.selectedInformation.vendor; 
NSLog(@"%@", self.editingNameField.text); 

}

Я не работает с обоими didSelectRow и prepareForSegue, это один или другой, но оба дают те же результаты.

NSLog дает мне NULL, и когда контроллер экрана появляется на экране, он не имеет никакой информации в этом поле.

Я перешел к этому новому контроллеру вида в раскадровке, поэтому не уверен, что я должен использовать prepareForSegue, но это тоже не сработало.

Мой вопрос: мне нужно сделать какую-то выборку в DetailViewController в Core Data?

Что нужно сделать, чтобы заставить это работать?

Спасибо!

+0

Если вы используете segue, вы должны использовать 'prepareForSegue'. Покажите этот код. – Wain

+0

Спасибо @Wain - я обновил код, чтобы отразить это. – amitsbajaj

ответ

1

Ваших 2 подходов имеют различные проблемы:

При использовании didDeselectRowAtIndexPath и viewDidLoad, ваша проблема в том, что вы создаете контроллер представления, который никогда не помещается на экране (потому что другой один создается Segue).

Когда вы используете prepareForSegue, ваша проблема заключается в том, что вы вызываете setSelectedInformation, и он сразу же пытается взаимодействовать с editingNameField, и этого еще нет (потому что представление не было загружено).

Итак, вы должны использовать prepareForSegue, но вам также необходимо использовать viewDidLoad. Установите информацию в контроллер точки назначения. В пункте назначения, примените эти данные к представлению, когда оно было загружено.

Наконец, с точки отладки - регистрируйте исходные данные, а не только результат. Это приведет вас к источнику проблемы.

+0

Спасибо @Wain - что сделал. Я придерживался подхода prepareForSegue и с помощью viewDidLoad, и все проходит хорошо. Большое спасибо - высоко оценили! – amitsbajaj

1

Если вы используете storyBoards, вы обязательно должны сделать свой переход информации в метод prepareForSegue, так как storyBoard сам создаст экземпляр вашего контроллера представлений.

В вашем методе didSelect:

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Information *information = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    // Save your selected information for later 
    self.selectedInformation = information; 

}

В вашем методе prepareForSegue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"DetailViewSegue"]) 
    { 
     DetailViewController *dvc = (DetailViewController *)segue.destinationViewController; 
     dvc.selectedInformation = self.selectedInformation; 
    } 
} 

Это должно сделать это!

+0

Благодарим за ответ. Я пробовал это и, к сожалению, все еще получаю тот же результат, хотя теперь NSLog не выглядит так, как будто он работает, что означает, что я могу понять, почему это не работает. NSLog находится в viewDidLoad. Я создал свойство Information * selectedInformation в TableView, так что, когда я помещаю self.selectedInformation в didSelect, он вызывает это. У меня также есть информация * selectedInformation в DVC .. Я подозреваю, что мы почти там! Я пытаюсь понять, почему NSLog не запускается вообще – amitsbajaj

+0

Первое, что я использовал неправильный метод :) Я использовал didDESELECT .. - теперь это работает с вашим кодом, но это не так дайте мне выбранную ячейку все время. Если у меня есть ячейка 1 и нажмите ее, она покажет мне ячейку 1 .. если я вернусь и щелкнув ячейку 2, она снова покажет мне ячейку 1. Если я вернусь и щелкнув по ячейке 3, он показывает мне ячейку 2 – amitsbajaj

+0

Я думаю, вы можете добавить 'self.selectedInformation = nil' в конце подготовкиForSegue? – shinyuX

Смежные вопросы