在核心数据/UITableView 上对数据刷新(软删除)进行动画处理



我有一个由fetchedResultsController支持的表视图。在我的表格单元格上,我有一个执行软删除的按钮,就视图而言......点击按钮,将调用执行软删除的选择器,然后...应该会发生一些事情(我已经尝试了很多事情),但我尝试过的动画都不像Apple的行动画那样。

我可以执行简单的行动画,例如让它滑开(在我告诉表重新加载之前留下一个空白行,这反过来又有点不和谐的效果)。这是我最接近的:

-(void) completeTask: (id) sender {     NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];     NSDate *date = [[NSDate alloc] init];     NSManagedObject *task = [self.fetchedResultsController objectAtIndexPath:indexPath];     [任务集值:日期键:@"完成"];     AppController *ac = [AppController sharedAppController];     NSManagedObjectContext *moc = [ac managedObjectContext];     NSError *error = nil;     如果(![moc save:&error]){         NSLog(@"%@ %@",error, [error description]);         退出(-1);     } else {         UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];         CGRect cellFrame = cell.frame;         [UIView beginAnimations:nil context:nil];         [UIView set动画持续时间:0.35];         [UIView setAnimationDelegate:self];         [UIView setAnimationDidStopSelector:@selector(someAnimationDidStop:done:context:)];         cell.frame = CGRectMake(cellFrame.size.width , cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height);         [UIView commitAnimations];     } }-(void) someAnimationDidStop:(NSString *)animationID                    已完成:(布尔值)已完成上下文:(无效 *)持续时间 {    NSLog(@"动画停止");    [自取结果];这家伙执行新的获取和表数据重新加载}

我觉得我走在正确的轨道上,但我不认为这真的是答案。我希望以某种方式controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:会是答案。我的猜测是,如果我想要苹果动画,我将不得不创建一个单独的NSMutableArray来跟踪结果,并确保它保持同步。

想法和意见?

谢谢!!!

我想你已经有一个不获取那些"软删除"对象的NSFetchedResultsController谓词。

所以从理论上讲,你所要做的就是实现所有的NSFetchResultsControllerDelegate方法。文档中的示例实现将正常工作。
不要忘记设置NSFetchedResultsControllerdelegate

然后,只需更改对象的"软删除"值,而不是手动管理单元格。NSFetchResultsController 将监视上下文,它发现此更改会使对象从集合中消失,因此它将从表视图中删除单元格。

编辑:@fluchtpunkt答案是正确的。在对我的代码进行了一些更新后,我的解决方案再次中断。删除重新获取 FRC 的块使其再次工作。


我很惊讶我昨天在所有迭代测试(学习)中都没有弄清楚这一点。我在以一种很好的方式将获取的核心数据获取结果与表视图同步时遇到了问题 - 通常我会得到不匹配的索引(等等等等,行数 (#) 必须等于数字 # 加上或减去行数等等等等(插入 0:# 已删除).. 等等)。

我完成此操作的步骤如下:

  1. 执行软删除和保存
  2. 将提取的结果控制器设置为 NIL self.fetchedrResultsController = nil
  3. 执行新的抓取
  4. 然后从表中删除该行:
self.fetchedResultsController = nil;         NSError *error = nil;         如果(![[self fetchedResultsController] performFetch:&error]) {             NSLog(@"未解决的错误 %@, %@", error, [error userInfo]);             中止();         } else {             [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];         }

我真的不知道为什么我没有早点弄清楚这一点,但这很有意义。新鲜的眼睛?

以下是全图:

-(void) completeTask: (id) sender {     NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];     NSManagedObject *task = [self.fetchedResultsController objectAtIndexPath:indexPath];     [任务集值:日期键:@"完成"];     AppController *ac = [AppController sharedAppController];     NSManagedObjectContext *moc = [ac managedObjectContext];     NSError *error = nil;     如果(![moc save:&error]){         NSLog(@"呃哦 - 无法保存删除!%@ %@",错误,[错误描述]);         退出(-1);     } else {         保存成功;重新获取数据(后台)         self.fetchedResultsController = nil;         NSError *error = nil;         如果(![[self fetchedResultsController] performFetch:&error]) {             NSLog(@"未解决的错误 %@, %@", error, [error userInfo]);             中止();         } else {             使用行动画更新表视图             [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]                                   与行动画:UITableViewRowAnimationRight];         }     } }

最新更新