Core Data / UITableView 上的动画数据刷新(软删除)
我有一个由 fetchedResultsController 支持的表视图。在我的表格单元格上,我有一个执行软删除的按钮,就视图而言...点击按钮,执行软删除的选择器被调用,并且...应该会发生一些事情(我'我尝试过很多东西),但我尝试过的动画都没有像苹果的行动画那样。
我可以执行简单的行动画,比如让它滑开(这会留下一个空白行,直到我告诉表格重新加载,这反过来又有点不和谐的效果)。这是我最接近的:
-(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 来跟踪结果并确保它保持同步。
想法和意见?
谢谢!!!
I have a table view that's backed by a fetchedResultsController. On my table cells I have a button that performs a soft delete, as far as the view is concerned... tap the button, the selector that performs the soft delete is called, and ... something is supposed to happen (I've tried a lot of things), but nothing I've tried animates like Apple's row animations.
I can perform simple row animations, like making it slide out of the way (which leaves a blank row until I tell the table to reload, which in turn is a bit of a jarring effect). This is the closest I've come:
-(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 }
I feel like I'm sort of on the right track, however I don't think this is really quite the answer. I was hoping that somehow controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
would be the answer. My guess is that if I want the stock Apple animations, I will have to create a separate NSMutableArray to track the results and just make sure it's kept in sync.
Thoughts and opinions?
Thanks!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜您已经有一个
NSFetchedResultsController
谓词,它不会获取那些“软删除”对象。因此,理论上您所要做的就是实现 NSFetchResultsControllerDelegate 方法。文档中的示例实现可以正常工作。
不要忘记设置
NSFetchedResultsController
的delegate
然后,无需手动管理单元格,只需更改对象中的“软删除”值即可。 NSFetchResultsController 将监视上下文,它发现此更改使对象从集合中消失,因此它将从 tableView 中删除单元格。
I guess you have already a predicate for the
NSFetchedResultsController
that doesn't fetch those "soft deleted" objects.So in theory all you have to do is to implement all of the NSFetchResultsControllerDelegate methods. The sample implementation from the documentation will work fine.
Don't forget to set the
delegate
of theNSFetchedResultsController
Then instead of manually managing cells, just change the "soft delete" value from the object. The NSFetchResultsController will monitor the context, it figures out that this change make the object disappear from the collection so it will remove the cell from the tableView.
编辑:@fluchtpunkt 答案是正确的。对我的代码进行了一些更新后,我的解决方案再次崩溃了。删除重新获取 FRC 的块使其再次正常工作。
我很惊讶我在昨天的所有迭代测试(学习)中都没有弄清楚这一点。我在以一种很好的方式将核心数据获取结果与表视图同步时遇到了问题 - 通常我会得到不匹配的索引(等等行数 (#) 必须等于数字 # 加或减去行数等等(插入 0:# 删除).. 等等)。
我完成此操作的步骤如下:
self.fetchedrResultsController = nil
我真的不知道为什么我没有早点弄清楚这一点,但它很有道理。新鲜的眼睛?
这是完整的图片:
EDIT: @fluchtpunkt answer is correct. After making a few more updates to my code my solution broke again. Removing the the block that re-fetches the FRC made it all work again.
I'm surprised I didn't figure this out in all my iterative testing (learning) yesterday. I was had run into problems with syncing the core data fetched results with the table view in a nice way - often I'd get the mis-match index (blah blah blah the number of rows (#) must equal the number # plus or minus the number of rows blah blah blah ( 0 inserted: # deleted).. etc).
My steps to complete this were as follows:
self.fetchedrResultsController = nil
I really don't know why I didn't figure this out earlier, but it makes so much sense. Fresh eyes?
Here's the full picture: