2011-08-04 9 views
15

Mam raczej wanilię UITableView zarządzaną przez NSFetchedResultsController, aby wyświetlić wszystkie wystąpienia danej encji Core Data.tableView: cellForRowAtIndexPath wywoływana z zerową ścieżką IndexPath po usunięciu elementu

Gdy użytkownik kasuje wpisu w widoku tabeli, przesuwając nad nim, tableView:cellForRowAtIndexPath: ostatecznie zostanie wywołany na moim UITableViewController z nilindexPath. Ponieważ nie spodziewałem się, że zostanie wywołany z nilindexPath, aplikacja ulega awarii.

mogę obejść katastrofie przez sprawdzenie tej wartości nil a następnie powrocie pustą komórkę. To wydaje się działać, ale nadal martwię się, że mogłem sobie poradzić z czymś złym. Jakieś pomysły? Czy ktokolwiek widział tableView:cellForRowAtIndexPath: z numerem nilindexPath?

Zauważ, że to się dzieje tylko wtedy, gdy użytkownik usuwa z widoku tabeli, przesuwając na komórkę. Podczas usuwania elementu przy użyciu trybu edycji widoku tabeli, tak się nie dzieje. Czym różni się ten sposób usuwania komórki?

Czy to naprawdę OK, aby uzyskać nilindexPath w metodzie delegata widoku tabeli?

Mój kod widok kontroler jest naprawdę norma. Oto delecja:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the row from the data source 
     NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     [self.moc deleteObject:managedObject]; 
     NSError *error = NULL; 
     Boolean success = [self.moc save:&error]; 
     if (!success) { <snip> } 
     // actual row deletion from table view will be handle from Fetched Result Controller delegate 
     // [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } else { <snip> } 
} 

Doprowadzi to do sposobu NSFetchedResultsController delegata miano:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
    atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
    newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    UITableView *tableView = self.tableView; 
    switch(type) { 

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

     case NSFetchedResultsChangeInsert: <snip> break; 
     case NSFetchedResultsChangeUpdate: <snip> break; 
     case NSFetchedResultsChangeMove: <snip> break; 
    } 
} 

I oczywiście, metody źródła danych są obsługiwane przez NSFetchedResultsController, np:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo numberOfObjects]; 
} 

Dziękujemy.

+1

Czy zweryfikować wszystkie te nazywa się w przewidywanym porządku? – Mundi

+1

Spróbuj zadzwonić 'reloadData' na widoku tabeli w' Tableview: commitEditingStyle: forRowAtIndexPath' natychmiast * po * zapisywania zmian w kontekście zarządzanego obiektu. Miałem podobny problem z tym i ponowne załadowanie widoku tabeli naprawiło to. – Greg

Odpowiedz

0

Zrobiłbym to tak, ponieważ wypełniasz tabelę bezpośrednio z zarządzanego kontekstu, czemu nie po usunięciu najpierw usuń obiekt z zarządzanego kontekstu, a następnie natychmiast zaktualizuj tabelę z kontekstu, używając reloadData. Ale przy użyciu podejścia myślę trzeba dodać beginUpdates i endUpdates:

#pragma mark - 
#pragma mark Fetched results controller delegate 


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


- (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:UITableViewRowAnimationFade]; 
     break; 

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


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

UITableView *tableViews = self.tableView; 

switch(type) { 

    case NSFetchedResultsChangeInsert: 
     [tableViews insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [tableViews deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [_delegate configureCell:[tableViews cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
     break; 

    case NSFetchedResultsChangeMove: 
     [tableViews deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableViews insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
} 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    [self.tableView scrollToRowAtIndexPath:indexPath 
         atScrollPosition:UITableViewScrollPositionMiddle 
           animated:NO]; 
} 
2

Wydaje się, że usuwasz indexPath z tabeli, ale źródło danych tabeli nie aktualizuje. Czy weryfikacja procesu udoskonalania źródła danych przez NSFetchedResultsController poprawnie aktualizuje źródło danych tabeli?

-1

używam CoreData w widokach tabeli i pozwala użytkownikom na usuwanie rekordów i aktualizować je cały czas, mam je w 4 aplikacjach bez napotkania problemu wzmiance.

mam te FetchedResultsController Delegowanie metody w moim kodu

 - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates. 
    [self.myTableView beginUpdates]; 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
     [self.myTableView endUpdates]; 

}

Powiązane problemy