我有一个由NSFetchedResultsController填充的UITableView。
在表格的初始加载中,我希望在单元格中设置动画,但我想做比更多的自定义动画
[tableView insertRowsAtIndexPaths:withRowAnimation:];
允许。具体来说,我想放慢动画的速度,让它们以特定的方式从侧面飞进来。我无法通过UITableViewRowAnimation常量实现这一点。有没有一种方法可以使用核心动画来做我想要的事情,或者我需要在这个特定的实例中坚持使用UIKit动画?
谢谢你的帮助!
Joel
最新解决方案(2017-12-12)
添加Swift 4.0版本的animate方法。然后,它应该以与以下解决方案相同的方式实现:
func animate() {
for cell in self.tableView.visibleCells {
cell.frame = CGRect(x: self.tableView.frame.size.width, y: cell.frame.origin.y, width: cell.frame.size.width, height: cell.frame.size.height)
UIView.animate(withDuration: 1.0) {
cell.frame = CGRect(x: 0, y: cell.frame.origin.y, width: cell.frame.size.width, height: cell.frame.size.height)
}
}
}
最新解决方案(2015-09-05)
添加Swift 2.0版本的animate方法。然后,它应该以与以下解决方案相同的方式实现:
func animate() {
for cell in self.tableView.visibleCells {
cell.frame = CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)
UIView.animateWithDuration(1.0) {
cell.frame = CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)
}
}
}
新解决方案(2014-09-28)
我对解决方案进行了一些修改,使实现更加容易,并使其与iOS8一起工作。你所需要做的就是在TableViewController中添加这个animate
方法,并在你想让它动画化的时候调用它(例如,在你的重载方法中,但你可以随时调用它):
- (void)animate
{
[[self.tableView visibleCells] enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) {
[cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView animateWithDuration:1 animations:^{
[cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
}];
}];
}
再次,按照您喜欢的方式更改动画。此特定代码将以较慢的速率从右侧为单元格设置动画。
旧解决方案(2013-06-06)
您可以通过实现自己的UITableView并重写insertRowsAtIndexPaths方法来实现这一点。下面是一个例子,说明细胞将从右边缓慢地推到哪里(1秒动画):
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
for (NSIndexPath *indexPath in indexPaths)
{
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath];
[cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView beginAnimations:NULL context:nil];
[UIView setAnimationDuration:1];
[cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView commitAnimations];
}
}
你可以自己玩这些动画。此方法不会由表视图自动调用,因此您必须重写表视图委托中的reloadData方法,并自己调用此方法。
评论
reloadData方法应该看起来像这样:
- (void)reloadData
{
[super reloadData];
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
for (int i = 0; i < [_data count]; i++)
[indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
[self insertRowsAtIndexPaths:indexPaths withRowAnimation:0];
}
materik的答案对我的iOS 7.1 SDK不起作用,调用[self cellForRowAtIndexPath:indexPath];
后我得到了零
这是我在UITableView
:子类中的代码
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths
withRowAnimation:(UITableViewRowAnimation)animation
{
[super insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
[self endUpdates]; // Populates UITableView with data
[self beginUpdates];
for (NSIndexPath *indexPath in indexPaths) {
__block UITableViewCell *cell = [super cellForRowAtIndexPath:indexPath];
if (cell) { // If indexPath isn't visible we'll get nil here
// Custom animation
CGRect frame = cell.frame;
frame.origin.x = cell.frame.size.width;
cell.frame = frame;
frame.origin.x = 0;
void (^animationsBlock)() = ^{
cell.frame = frame;
};
if ([[UIView class] respondsToSelector:
@selector(animateWithDuration:delay:usingSpringWithDamping:
initialSpringVelocity:options:animations:completion:)]) {
[UIView animateWithDuration:0.3
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0
options:0
animations:animationsBlock
completion:NULL];
} else {
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:animationsBlock
completion:NULL];
}
}
}
}
使用此:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
[cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
[UIView animateWithDuration:2 animations:^{
[cell setFrame:CGRectMake(100, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
}];
}
Swift 3.0版本的Mattias Eriksson的Answer
func animate() {
for cell in tblView.visibleCells {
cell.frame = CGRect(x:320, y:cell.frame.origin.y, width:cell.frame.size.width, height:cell.frame.size.height)
UIView.animate(withDuration: 1.0) {
cell.frame = CGRect(x:0, y:cell.frame.origin.y, width:cell.frame.size.width, height:cell.frame.size.height)
}
}
}