How to Save Re-Ordered Tableview Cells to Core Data

Rearranging UITableView with Core Data

Here's what's officially working now, with deletes, moves, and inserts. I "validate" the order any time there's an edit action affecting the order.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section != kHeaderSection) {

if (editingStyle == UITableViewCellEditingStyleDelete) {

@try {
LinkObj * link = [self.fetchedResultsController objectAtIndexPath:indexPath];

debug_NSLog(@"Deleting at indexPath %@", [indexPath description]);
//debug_NSLog(@"Deleting object %@", [link description]);

if ([self numberOfBodyLinks] > 1)
[self.managedObjectContext deleteObject:link];

}
@catch (NSException * e) {
debug_NSLog(@"Failure in commitEditingStyle, name=%@ reason=%@", e.name, e.reason);
}

}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// we need this for when they click the "+" icon; just select the row
[theTableView.delegate tableView:tableView didSelectRowAtIndexPath:indexPath];
}
}
}

- (BOOL)validateLinkOrders {
NSUInteger index = 0;
@try {
NSArray * fetchedObjects = [self.fetchedResultsController fetchedObjects];

if (fetchedObjects == nil)
return NO;

LinkObj * link = nil;
for (link in fetchedObjects) {
if (link.section.intValue == kBodySection) {
if (link.order.intValue != index) {
debug_NSLog(@"Info: Order out of sync, order=%@ expected=%d", link.order, index);

link.order = [NSNumber numberWithInt:index];
}
index++;
}
}
}
@catch (NSException * e) {
debug_NSLog(@"Failure in validateLinkOrders, name=%@ reason=%@", e.name, e.reason);
}
return (index > 0 ? YES : NO);
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
NSArray * fetchedObjects = [self.fetchedResultsController fetchedObjects];
if (fetchedObjects == nil)
return;

NSUInteger fromRow = fromIndexPath.row + NUM_HEADER_SECTION_ROWS;
NSUInteger toRow = toIndexPath.row + NUM_HEADER_SECTION_ROWS;

NSInteger start = fromRow;
NSInteger end = toRow;
NSInteger i = 0;
LinkObj *link = nil;

if (toRow < start)
start = toRow;
if (fromRow > end)
end = fromRow;

@try {

for (i = start; i <= end; i++) {
link = [fetchedObjects objectAtIndex:i]; //
//debug_NSLog(@"Before: %@", link);

if (i == fromRow) // it's our initial cell, just set it to our final destination
link.order = [NSNumber numberWithInt:(toRow-NUM_HEADER_SECTION_ROWS)];
else if (fromRow < toRow)
link.order = [NSNumber numberWithInt:(i-1-NUM_HEADER_SECTION_ROWS)]; // it moved forward, shift back
else // if (fromIndexPath.row > toIndexPath.row)
link.order = [NSNumber numberWithInt:(i+1-NUM_HEADER_SECTION_ROWS)]; // it moved backward, shift forward
//debug_NSLog(@"After: %@", link);
}
}
@catch (NSException * e) {
debug_NSLog(@"Failure in moveRowAtIndexPath, name=%@ reason=%@", e.name, e.reason);
}
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
@try {
switch (type) {
case NSFetchedResultsChangeInsert:
[theTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self validateLinkOrders];
break;
case NSFetchedResultsChangeUpdate:
break;
case NSFetchedResultsChangeMove:
self.moving = YES;
[self validateLinkOrders];
break;
case NSFetchedResultsChangeDelete:
[theTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self validateLinkOrders];
break;
default:
break;
}
}
@catch (NSException * e) {
debug_NSLog(@"Failure in didChangeObject, name=%@ reason=%@", e.name, e.reason);
}
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.theTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
@try {
if (self.theTableView != nil) {
//[self.theTableView endUpdates];
if (self.moving) {
self.moving = NO;
[self.theTableView reloadData];
//[self performSelector:@selector(reloadData) withObject:nil afterDelay:0.02];
}
[self performSelector:@selector(save) withObject:nil afterDelay:0.02];
}

}
@catch (NSException * e) {
debug_NSLog(@"Failure in controllerDidChangeContent, name=%@ reason=%@", e.name, e.reason);
}
}

How to save tableView order after reordering cells in swift 4

You'll need to have some sort of property (attribute) in your core data model so that you can save the order number into the database. That way, when you fetch, you can use a sort descriptor to sort on the order number.



Related Topics



Leave a reply



Submit