2011-05-06 158 views
1

我有一个由fetchedResultsController支持的表视图。在我的表格单元格中,我有一个执行软删除的按钮,就视图而言...点击按钮,执行软删除的选择器被调用,并且...应该发生某事(I'我尝试了很多东西),但没有尝试过像Apple的行动画那样的动画。核心数据/ UITableView上的动画数据刷新(软删除)

我可以执行简单的行动画,就像使其滑动一样(在我告诉表重新加载之后会留下一个空行),这反过来又有点刺耳的效果)。这是我来最接近:

 -(void) completeTask: (id) sender { 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]]; 

    NSDate *date = [[NSDate alloc] init]; 
    NSManagedObject *task = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

    [task setValue:date forKey:@"complete"]; 

    AppController *ac = [AppController sharedAppController]; 
    NSManagedObjectContext *moc = [ac managedObjectContext]; 

    NSError *error = nil; 
    if(![moc save:&error]){ 
     NSLog(@"%@ %@",error, [error description]); 
     exit(-1); 
    } else { 
     UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 

     CGRect cellFrame = cell.frame; 
     [UIView beginAnimations:nil context:nil]; 
     [UIView setAnimationDuration:0.35]; 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationDidStopSelector:@selector(someAnimationDidStop:finished:context:)]; 
     cell.frame = CGRectMake(cellFrame.size.width , cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); 
     [UIView commitAnimations]; 
    } 
} 

-(void) someAnimationDidStop:(NSString *)animationID 
        finished:(BOOL)finished context:(void *)duration { 
    NSLog(@"Animation Stopped"); 
    [self fetchResults]; // this guy performs a new fetch and table data reload 
} 

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

思想和观点?

谢谢!

回答

1

我想你已经为NSFetchedResultsController不取的“软删除”对象的谓词。

所以理论上你所要做的就是实施NSFetchResultsControllerDelegate方法的全部。文档中的示例实现将正常工作。
不要忘记设置的NSFetchedResultsController

delegate然后代替手工管理的细胞,只是改变从对象的“软删除”值。NSFetchResultsController将监视上下文,它会发现这种更改会使对象从集合中消失,因此它将从tableView中删除单元格。

+0

你是对的 - 在对我的委托方法进行一些更改以正确启用真正的删除后,看起来我的答案在下面停止工作,直到我删除了手动表管理。谢谢! – Cameron 2011-05-09 19:38:05

1

编辑:@fluchtpunkt答案是正确的。在对代码进行更多更新之后,我的解决方案再次崩溃。删除重新获取FRC的块使其全部重新工作。


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

我的步骤来完成此如下:

  1. 执行软删除&保存
  2. 获取的成果控制器设置为nil self.fetchedrResultsController = nil
  3. 做一个新的获取
  4. 然后删除该行来自表格:
   self.fetchedResultsController = nil; 
     NSError *error = nil; 
     if (![[self fetchedResultsController] performFetch:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 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]; 

    [task setValue:date forKey:@"complete"]; 

    AppController *ac = [AppController sharedAppController]; 
    NSManagedObjectContext *moc = [ac managedObjectContext]; 

    NSError *error = nil; 
    if(![moc save:&error]){ 
     NSLog(@"Uh oh - couldn't save the delete! %@ \n%@",error, [error description]); 
     exit(-1); 
    } else { 

     // Save successful; re-fetch data (background) 
     self.fetchedResultsController = nil; 
     NSError *error = nil; 
     if (![[self fetchedResultsController] performFetch:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } else { 
      //update the table view with row animation 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
            withRowAnimation:UITableViewRowAnimationRight]; 
     } 
    } 
}