Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
363 views
in Technique[技术] by (71.8m points)

objective c - Can you do custom animations for UITableView Cell Inserts?

I've got a UITableView that is being populated by an NSFetchedResultsController.

On the initial load of the table I would like the Cells to be animated in but I would like to do a little bit more custom animation than

[tableView insertRowsAtIndexPaths:withRowAnimation:];

Allows. Specifically I would like to slow down the animations and have them fly in from the side in a specific way. I have not been able to achieve this by UITableViewRowAnimation constants. Is there a way to use Core Animation to do exactly what I want or do I need to stick with UIKit animations in this specific instance?

Thanks for any help!

Joel

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

NEWEST SOLUTION (2017-12-12)

Adding a Swift 4.0 version of the animate method. It should then be implemented in the same way as the solution below:

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)
        }
    }
}

NEWER SOLUTION (2015-09-05)

Adding a Swift 2.0 version of the animate method. It should then be implemented in the same way as the solution below:

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)
        }
    }
}

NEW SOLUTION (2014-09-28)

I reworked the solution a bit to make the implementation more easier and to make it work with iOS8. All you need to do is to add this animate method in your TableViewController and call it whenever you want it to animate (for instance, in your reload method, but you could call it at any time):

- (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)];
        }];
    }];
}

Again, change the animation how you like. This particular code will animate the cells in from the right at a slow rate.

OLD SOLUTION (2013-06-06)

You can do this by implementing your own UITableView and overriding the insertRowsAtIndexPaths method. Here is an example of how that could look like where the cells will be pushed from the right, really slowly (1 second animation):

- (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];
    }
}

You can play around with the animations yourself. This method will not be called automatically by the table view so you have to override the reloadData method in your table view delegate and call this method yourself.

COMMENT

The reloadData method should look something like this:

- (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];
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...