我有一个UITableView有两种模式.当我们在模式之间切换时,每个部分有不同数量的部分和单元格.理想情况下,当表增长或缩小时,它会做一些很酷的动画.
这是我尝试过的代码,但它没有做任何事情:
CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:0.5]; [self.tableView reloadData]; [UIView commitAnimations];
有关如何做到这一点的任何想法?
实际上,它很简单:
[_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
从文档:
调用此方法会导致表视图向其数据源询问指定节的新单元格.表格视图为新单元格的插入设置动画,因为它会将旧单元格设置为动画.
您可能想要使用:
Objective-C的
[UIView transitionWithView: self.tableView duration: 0.35f options: UIViewAnimationOptionTransitionCrossDissolve animations: ^(void) { [self.tableView reloadData]; } completion: nil];
迅速
UIView.transitionWithView(tableView, duration: 0.35, options: .TransitionCrossDissolve, animations: { () -> Void in self.tableView.reloadData() }, completion: nil);
斯威夫特3
UIView.transition(with: tableView, duration: 0.35, options: .transitionCrossDissolve, animations: { self.tableView.reloadData() }) // left out the unnecessary syntax in the completion block and the optional completion parameter
没有麻烦.:d
您还可以使用任何UIViewAnimationOptionTransitions
您想要的冷却效果:
TransitionNone
TransitionFlipFromLeft
TransitionFlipFromRight
TransitionCurlUp
TransitionCurlDown
TransitionCrossDissolve
TransitionFlipFromTop
TransitionFlipFromBottom
CATransition
课堂有更多的自由.
(别忘了导入QuartzCore
)
CATransition *transition = [CATransition animation]; transition.type = kCATransitionPush; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; transition.fillMode = kCAFillModeForwards; transition.duration = 0.5; transition.subtype = kCATransitionFromBottom; [[self.tableView layer] addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];
更改type
以满足您的需求,例如kCATransitionFade
等.
let transition = CATransition() transition.type = kCATransitionPush transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) transition.fillMode = kCAFillModeForwards transition.duration = 0.5 transition.subtype = kCATransitionFromTop self.tableView.layer.addAnimation(transition, forKey: "UITableViewReloadDataAnimationKey") // Update your data source here self.tableView.reloadData()
CATransition的参考
我相信你可以只更新你的数据结构,然后:
[tableView beginUpdates]; [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]; [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]; [tableView endUpdates];
此外,"withRowAnimation"不是一个布尔值,而是一个动画风格:
UITableViewRowAnimationFade, UITableViewRowAnimationRight, UITableViewRowAnimationLeft, UITableViewRowAnimationTop, UITableViewRowAnimationBottom, UITableViewRowAnimationNone, UITableViewRowAnimationMiddle
所有这些答案都假设您使用的UITableView只有1个部分.
要准确处理您有超过1个部分使用的情况:
NSRange range = NSMakeRange(0, myTableView.numberOfSections); NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; [myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
(注意:你应该确保你有超过0个部分!)
另一件需要注意的事情是,如果您尝试使用此代码同时更新数据源,则可能会遇到NSInternalInconsistencyException.如果是这种情况,您可以使用与此类似的逻辑:
int sectionNumber = 0; //Note that your section may be different int nextIndex = [currentItems count]; //starting index of newly added items [myTableView beginUpdates]; for (NSObject *item in itemsToAdd) { //Add the item to the data source [currentItems addObject:item]; //Add the item to the table view NSIndexPath *path = [NSIndexPath indexPathForRow:nextIndex++ inSection:sectionNumber]; [myTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationAutomatic]; } [myTableView endUpdates];
解决这个问题的方法是告诉tableView删除并添加行和节
insertRowsAtIndexPaths:withRowAnimation:
,
deleteRowsAtIndexPaths:withRowAnimation:
,
insertSections:withRowAnimation:
和
deleteSections:withRowAnimation:
UITableView的方法.当您调用这些方法时,该表将为您请求的项目设置动画,然后在其自身上调用reloadData,以便您可以在此动画后更新状态.这一部分很重要 - 如果您动画掉所有内容但不更改表格dataSource返回的数据,则动画完成后会再次显示这些行.
那么,您的申请流程将是:
[self setTableIsInSecondState:YES];
[myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];
只要表的dataSource方法通过检查[self tableIsInSecondState]
(或其他)返回正确的新的节和行集,这将实现您正在寻找的效果.
我无法评论最佳答案,但快速实施将是:
self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)
您可以在reloadSections的第一个参数中包含要更新的部分.
其他动画可从文档中获得:https: //developer.apple.com/reference/uikit/uitableviewrowanimation
淡入淡出 插入或删除的一行或多行淡入或淡出表视图.
right 插入的一行或多行从右侧滑入; 删除的一行或多行向右滑动.
left 插入的一行或多行从左侧滑入; 删除的一行或多行向左滑动.
顶部 插入的一行或多行从顶部滑入; 删除的一行或多行向上滑动.
底部 插入的一行或多行从底部滑入; 删除的一行或多行向下滑动.
case none 插入或删除的行使用默认动画.
中间 表视图尝试将旧单元和新单元保持在它们所占用或将占用的空间中心.适用于iPhone 3.2.
自动 表视图为您选择适当的动画样式.(在iOS 5.0中引入.)
适用于@dmarnel的Swift 4版本答案:
tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
快速实施:
let range = NSMakeRange(0, self.tableView!.numberOfSections()) let indexSet = NSIndexSet(indexesInRange: range) self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
对于Swift 4
tableView.reloadSections([0], with: UITableView.RowAnimation.fade)