Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于核心数据对象的UITableView单元格插入/删除算法?_Uitableview_Core Data_Delete Row - Fatal编程技术网

基于核心数据对象的UITableView单元格插入/删除算法?

基于核心数据对象的UITableView单元格插入/删除算法?,uitableview,core-data,delete-row,Uitableview,Core Data,Delete Row,我有一个核心数据配方对象,它包含成分对象的有序列表 成分在UITableView中显示为列表。当用户取消对表格视图的编辑时,我在MOC上调用rollback,这可能会恢复一些成分(用户删除的成分)并删除其他成分(用户添加的成分)。我想设置插入/删除的动画,这样过渡就不会产生不和谐 这比一开始看起来要困难一些,特别是当你插入和移除同一个单元格时,UITableView会砍掉一个毛球 是否有一些示例代码可以帮助我朝着正确的方向前进?现在我有一个使用NSMutableSets的极其复杂的设置,它不太正

我有一个核心数据配方对象,它包含成分对象的有序列表

成分在UITableView中显示为列表。当用户取消对表格视图的编辑时,我在MOC上调用
rollback
,这可能会恢复一些成分(用户删除的成分)并删除其他成分(用户添加的成分)。我想设置插入/删除的动画,这样过渡就不会产生不和谐

这比一开始看起来要困难一些,特别是当你插入和移除同一个单元格时,UITableView会砍掉一个毛球

是否有一些示例代码可以帮助我朝着正确的方向前进?现在我有一个使用NSMutableSets的极其复杂的设置,它不太正常

NSMutableArray *preIngredients = [NSMutableArray arrayWithArray:[recipe orderedIngredients]];

[self.recipe.managedObjectContext rollback];

NSMutableArray *postIngredients = [NSMutableArray arrayWithArray:[recipe orderedIngredients]];

NSMutableSet *beforeIngredients = [NSMutableSet setWithArray:preIngredients];
NSMutableSet *afterIngredients = [NSMutableSet setWithArray:postIngredients];

NSMutableSet *restoredIngredients = [NSMutableSet setWithSet:afterIngredients];
[restoredIngredients minusSet:beforeIngredients];

NSMutableSet *removedIngredients = [NSMutableSet setWithSet:beforeIngredients];
[removedIngredients minusSet:afterIngredients];

NSMutableSet *allIngredients = [NSMutableSet setWithSet:beforeIngredients];
[allIngredients unionSet:afterIngredients];

int whatToDo[[preIngredients count]];
for (int i = 0; i < [preIngredients count]; i++)
    whatToDo[i] = 0;

for (Ingredient *ingredient in preIngredients) {
    int row = [preIngredients indexOfObject:ingredient];

    if ([removedIngredients containsObject:ingredient])
        whatToDo[row]--;

    if ([restoredIngredients containsObject:ingredient])
        whatToDo[row]++;
}

for (int i = 0; i < [preIngredients count]; i++) {
    if (whatToDo[i] < 0)
        [rowsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:0]];
    else if (whatToDo[i] > 0)
        [rowsToRestore addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}

    // Also remove the "add new ingredient" cell
NSIndexPath *insertNewCellIndexPath = [NSIndexPath indexPathForRow:[preIngredients count] inSection:0];
if ([rowsToRestore indexOfObjectIdenticalTo:insertNewCellIndexPath] == NSNotFound)
    [rowsToRemove addObject:insertNewCellIndexPath];
else
    [rowsToRestore removeObjectIdenticalTo:insertNewCellIndexPath];

[self.tableView insertRowsAtIndexPaths:rowsToRestore withRowAnimation:UITableViewRowAnimationTop];
[self.tableView deleteRowsAtIndexPaths:rowsToRemove withRowAnimation:UITableViewRowAnimationTop];
NSMutableArray*PreComponents=[NSMutableArray arrayWithArray:[recipe OrderedIngredents]];
[self.recipe.managedObjectContext回滚];
NSMUTABLEARRY*postIngredients=[NSMUTABLEARRY arrayWithArray:[recipe orderedIngredients]];
NSMutableSet*BeforeComponents=[NSMutableSet-setWithArray:PreComponents];
NSMutableSet*AfterComponents=[NSMutableSet-setWithArray:PostingElements];
NSMutableSet*RestoredingRents=[NSMutableSet-setWithSet:AfterComponents];
[RestoredGredients minusSet:在配料之前];
NSMutableSet*RemovedComponents=[NSMutableSet setWithSet:BeforeComponents];
[移除的配料:后配料];
NSMutableSet*AllingElements=[NSMutableSet setWithSet:BeforeComponents];
[AllingCredits unionSet:AfterComponents];
int whatToDo[[成分前计数];
对于(int i=0;i<[成分前计数];i++)
whatToDo[i]=0;
用于(成分*预成分中的成分){
int行=[PreComponents indexOfObject:Component];
如果([移除的配料包含对象:配料])
干什么;
如果([恢复的成分包含对象:成分])
whatToDo[行]+;
}
对于(int i=0;i<[成分前计数];i++){
if(whatToDo[i]<0)
[rowsToRemove addObject:[NSIndexPath indexPathForRow:i第0节]];
else if(whatToDo[i]>0)
[rowsToRestore addObject:[NSIndexPath indexPathForRow:i第1节:0]];
}
//同时移除“添加新成分”单元
NSIndexPath*insertNewCellIndexPath=[NSIndexPath indexPathForRow:[PreComponents count]子组:0];
if([rowsToRestore IndexOfobObjectIdenticalTo:insertNewCellIndexPath]==NSNotFound)
[rowsToRemove addObject:insertNewCellIndexPath];
其他的
[rowsToRestore removeObjectIdenticalTo:insertNewCellIndexPath];
[self.tableView insertRowsAtIndexPaths:rowsToRestore with RowAnimation:UITableViewRowAnimationTop];
[self.tableView deleteRowsAndExpaths:RowstoreMovewithRowAnimation:UITableViewRowAnimationTop];

您是否考虑过为此使用
NSUndoManager
?它应该将您的所有更改打包到一个事务中,您可以用一行代码将其退出。我建议查看关于此功能的

更新
使用NSUndoManager一点也不复杂。开始分组,然后结束分组。然后,如果需要,可以回滚这些更改。与您试图手动执行的跟踪相比,有几行代码

这是大量使用集合的工作代码。如果你知道一种简化它的方法,请毫不犹豫地说出来:)


谢谢我没有看到它,但它看起来更像是一个模型级(而不是控制器级)类。我终于想出了一个算法,尽管它仍然相当复杂。你应该更新你的问题,而不是像这样发布答案,除非你宣布这是我不同意的“正确答案”。
[self.tableView beginUpdates];

NSMutableArray *preIngredients = [NSMutableArray arrayWithArray:[recipe orderedIngredients]];
[self.recipe.managedObjectContext rollback];
NSMutableArray *postIngredients = [NSMutableArray arrayWithArray:[recipe orderedIngredients]];

NSMutableSet *beforeIngredients = [NSMutableSet setWithArray:preIngredients];
NSMutableSet *afterIngredients = [NSMutableSet setWithArray:postIngredients];

NSMutableSet *ingredientsToRestore = [NSMutableSet setWithSet:afterIngredients];
[ingredientsToRestore minusSet:beforeIngredients];

NSMutableSet *ingredientsToRemove = [NSMutableSet setWithSet:beforeIngredients];
[ingredientsToRemove minusSet:afterIngredients];

NSMutableSet *indexPathsToRestore = [NSMutableSet setWithCapacity:[ingredientsToRestore count]];
NSMutableSet *indexPathsToRemove = [NSMutableSet setWithCapacity:[ingredientsToRemove count]];

for (Ingredient *ingredient in ingredientsToRemove)
    [indexPathsToRemove addObject:[NSIndexPath indexPathForRow:[preIngredients indexOfObject:ingredient] inSection:0]];

// Also remove the "add new ingredient" row
[indexPathsToRemove addObject:[NSIndexPath indexPathForRow:[preIngredients count] inSection:0]];

for (Ingredient *ingredient in ingredientsToRestore)
    [indexPathsToRestore addObject:[NSIndexPath indexPathForRow:[postIngredients indexOfObject:ingredient] inSection:0]];

NSMutableSet *commonIndexPaths = [NSMutableSet setWithSet:indexPathsToRemove];
[commonIndexPaths intersectSet:indexPathsToRestore];

[indexPathsToRemove minusSet:commonIndexPaths];
[indexPathsToRestore minusSet:commonIndexPaths];

[self.tableView insertRowsAtIndexPaths:[indexPathsToRestore allObjects] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView deleteRowsAtIndexPaths:[indexPathsToRemove allObjects] withRowAnimation:UITableViewRowAnimationTop];

[self.tableView endUpdates];