2015-03-06 3 views
0

При удалении объекта из моих основных данных, который извлекается с помощью NSFetchedResultsController и отображается в TableView, он не обновляет таблицу. Он просто удаляет объект, но строка остается там до тех пор, пока я не поменяю местами представления и не вернусь. Я заметил, что этот вопрос только начинался с iOS8, но может быть неправильным. Ниже мой код:Редактирование табличного представления, содержащего NSFetchedResults

#pragma mark - Fetched Results Controller Delegate 

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 

    return YES; 
} 

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 

     NSManagedObjectContext * context = [self managedObjectContext]; 
     entity * rowToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

     [context deleteObject:rowToDelete]; 

     //check that the row has deleted data 
     NSLog(@"Shhiiiiiiiiii...... You done did delete a row..."); 

     NSError * error = nil; 
     if (![context save:&error]){ 
      NSLog(@"Error: %@", error); 
     } 

     //causes a crash 
     //[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight]; 

     //DOES NOT UPDATE THE TABLE   
     [self.tableView reloadData]; 
    } 

} 

Я использую все Normall делегатов так:

- (void) controllerWillChangeContent:(NSFetchedResultsController *)controller{ 
    [self.tableView beginUpdates]; 
} 

- (void) controllerDidChangeContent:(NSFetchedResultsController *)controller{ 
    [self.tableView endUpdates]; 
} 

- (void) controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{ 

switch (type) { 
    case NSFetchedResultsChangeInsert: 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationRight]; 
     break; 
    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight]; 
     break; 

    case NSFetchedResultsChangeUpdate:{ 
     entity * details = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 
     cell.textLabel.text = details.detailString; 
    } 
     break; 

    case NSFetchedResultsChangeMove: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    } 

} 

-(void) controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type{ 

switch (type) { 
    case NSFetchedResultsChangeInsert: 
     [self.tableView insertSections:[NSIndexSet indexSetWithIndex: sectionIndex] withRowAnimation:UITableViewRowAnimationRight]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationRight]; 
     break; 

    case NSFetchedResultsChangeMove: 
     NSLog(@"A table item was moved"); 
     break; 
    case NSFetchedResultsChangeUpdate: 
     NSLog(@"A table item was updated"); 
     break; 

    } 

} 

Я искал на стек и найти общий ответ «Вы должны использовать [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];». Это не работает.

Заранее благодарим за любую помощь. Если я не отвечаю сразу, это потому, что я принимаю передышку или; -)

ответ

0

я тупо помещен

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 

В начале, прежде чем действия могли бы обновить. Ошибка новичков. Надеюсь, это поможет кому-то еще, кто падает на одно и то же.

1

NSFetchedResultsController должен иметь возможность сообщать обо всех изменениях для вас.

  • Убедитесь, что функции обновления будут называться (т.е. сужать, где отказ может быть)
  • Убедитесь, что экземпляр NSFetchedResultsController имеет делегат установить
  • Убедитесь, что вы работаете то же самое, или подключен , контекст (т. е. проверить, что существует даже вероятность распространения уведомления)
  • Я не уверен, что вы можете игнорировать переупорядочение (может зависеть от вашего подхода), но представьте, что [объект A, строка 1] заменен с [объектом B, строка 2], тогда объект B удаляется, как система знает, какую строку таблицы удалить (если вы не сделаете что-то лишнее с информация)

В ручном удалении строки из таблицы может произойти сбой, поскольку источник данных будет не соответствовать таблице - таким образом, вызывая всевозможные путаницы. Методы делегата для получения результатов позволяют синхронизировать фактические результаты с результатами, показанными в таблице.

Я вырезал из рабочей демонстрации следующее (хотя и модифицировал кучу вещей в пути). Он работает и получает изменения и обновляет таблицу. Есть несколько сообщений в блогах только для Google, которые тоже помогут.

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    _fetchedResultsController = /* my fetched results controller... */; 
    _fetchedResultsController.delegate = self; 
} 

#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    NSInteger count = [[_fetchedResultsController sections] count]; 
    return count; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section]; 
    NSInteger count = [sectionInfo numberOfObjects]; 
    return count; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return [self configureCell:nil atIndexPath:indexPath]; 
} 


- (UITableViewCell *)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath { 
    id obj = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    if(!cell) { 
     cell = [self.tableView dequeueReusableCellWithIdentifier:@"MyTableViewCell" forIndexPath:indexPath]; 
    } 
    cell.textLabel.text = obj.someProperty; 
    return cell; 
} 

#pragma mark NSFetechResults delegate 

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo 
      atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 

    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 
     default: 
      break; 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath { 

    UITableView *tableView = self.tableView; 

    switch(type) { 

     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] 
        atIndexPath:indexPath]; 
      break; 
     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 
    } 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 
+0

Вы выделили одну вещь, что я был глуп, чтобы пропустить. Расположение контроллера '- (void) контроллераDidChangeContent: (NSFetchedResultsController *) { [self.tableView endUpdates]; } 'Это было все, что было не так –

+0

Также +1 для информации мой друг, пятно на –

+0

@SASmith Я действительно не понимаю, что исправить это из того, что вы говорите ... Вы предлагаете, чтобы порядок где он оказался в файле не так? Это не должно иметь значения! Я думаю, что основные моменты, которые следует предпринять из вышеизложенного, - это не перезагружать данные таблицы (нет необходимости), и не пытайтесь вручную обновлять вещи за пределами обычных методов делегатов NSFetchedResultsController. Наконец, убедитесь, что делегат установлен. – button

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