Objective c UITableView上的动画重新加载数据
您将如何在Objective c UITableView上的动画重新加载数据,objective-c,ios,cocoa-touch,uitableview,Objective C,Ios,Cocoa Touch,Uitableview,您将如何在UITableView上动画-重新加载数据?数据源位于UIFetchedResultsController上,因此我无法使用–insertSections:withRowAnimation:,–deleteSections:withRowAnimation:包装在–BeginUpdate,–EndUpdate中 编辑: 我想在NSFetchedResultsControllerrefetch之后调用-reloadData。您不能设置reloadData的动画。必须使用表视图的插入…、删
UITableView
上动画-重新加载数据
?数据源位于UIFetchedResultsController
上,因此我无法使用–insertSections:withRowAnimation:
,–deleteSections:withRowAnimation:
包装在–BeginUpdate
,–EndUpdate中
编辑:
我想在NSFetchedResultsController
refetch之后调用-reloadData
。您不能设置reloadData
的动画。必须使用表视图的插入…
、删除…
、移动…
和重新加载行…
方法使其具有动画效果
使用NSFetchedResultsController
时,这非常简单。NSFetchedResultsControllerDelegate
的文档包含一组示例方法,您只需根据自己的代码进行调整即可:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器{
[self.tableView开始更新];
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo
atIndex:(nsInteger)ChangeType:(NSFetchedResultsChangeType)类型的节索引{
开关(类型){
案例NSFetchedResultsChangesInsert:
[self.tableView insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)一个对象
atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)类型
newindepath:(nsindepath*)newindepath{
UITableView*tableView=self.tableView;
开关(类型){
案例NSFetchedResultsChangesInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
[self-configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexath];
打破
案例NSFetchedResultsChangeMove:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{
[self.tableView endUpdates];
}
我使用了分类方法
- (void)reloadData:(BOOL)animated
{
[self reloadData];
if (animated) {
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromBottom];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setFillMode:kCAFillModeBoth];
[animation setDuration:.3];
[[self layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];
}
}
可以使用以下方法制作重新加载数据的基本动画:
// Reload table with a slight animation
[UIView transitionWithView:tableViewReference
duration:0.5f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^(void) {
[tableViewReference reloadData];
} completion:NULL];
我根据来自的解决方案创建了一个UITableView
category方法
它应该重新加载所有表节。您可以使用UITableViewRowAnimation
选项播放不同的动画效果
- (void)reloadData:(BOOL)animated
{
[self reloadData];
if (animated)
{
[self reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.numberOfSections)] withRowAnimation:UITableViewRowAnimationBottom];
}
}
方法是:
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
如果要使用动画重新加载整个表,只需调用以下行:
NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]);
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];
您可能需要使用:
目标-C
/* Animate the table view reload */
[UIView transitionWithView:self.tableView
duration:0.35f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^(void)
{
[self.tableView reloadData];
}
completion:nil];
Swift
UIView.transitionWithView(tableView,
duration:0.35,
options:.TransitionCrossDissolve,
animations:
{ () -> Void in
self.tableView.reloadData()
},
completion: nil);
动画选项:
TransitionNone
从左到右的转换
从右到右的转换
过渡曲线上升
过渡曲线向下
过渡交叉溶解
从顶部翻转的转换
转换FlipFrombottom
Swift 5.1版本的answer@user500()
很抱歉,我没有提到在“refetch”之后需要重新加载表数据。我认为,它可以通过一些CALayer
动画来完成,整体上UITableView
。。。类似于复制表视图层、重新蚀刻、重新加载数据、设置层动画等功能…这是一个很好的答案,如果您需要自定义动画,这是一个很好的解决方案!我只有一件事要补充。在我的例子中,我遇到了一些问题,原因是在重新加载数据之前,TableView被全部滚动到底部,所以当动画发生时,它将所有单元格和表格的框架都搞乱了。我可以解决这个问题,确保在重新加载数据之前将tableView全部滚动到顶部:[self-scrollRectToVisible:CGRectMake(0,0,1,1)动画:否];我可以避免头部受到影响。我现在键入时,在表格标题中有一个搜索栏。整个表格都重新加载了动画,包括我正在键入的文本。我发现kCATransitionFade看起来比kCATransitionFromBottom好得多。非常好的解决方案,谢谢。小技巧:为了代码的可读性,方法签名实际上应该是reloadDataAnimated:(BOOL)animated
在任何其他转换上,直到您开始滚动时才重新加载tableview数据。知道为什么吗?当您更新不在主流程中的表时,该表可能不会自动更新。在这些情况下,您可以使用:[[NSRunLoop currentRunLoop]runUntelDate:[NSDate dateWithTimeIntervalSinceNow:0.01];这在动画块中吗?不管怎样,试错法说它应该在过渡的完成块中。谢谢!:)美好的我们正在寻找一个干净的解决方案,这是一个为那些不想调用暴力重新加载数据。。。。
UIView.transitionWithView(tableView,
duration:0.35,
options:.TransitionCrossDissolve,
animations:
{ () -> Void in
self.tableView.reloadData()
},
completion: nil);
func reloadData(_ animated: Bool) {
reloadData()
guard animated else { return }
let animation = CATransition()
animation.type = .push
animation.subtype = .fromBottom
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
animation.fillMode = .both
animation.duration = 0.3
layer.add(animation, forKey: "UITableViewReloadDataAnimationKey")
}