Stop UITableViewCells from animating when animating a UITableView
Asked Answered
S

4

8

I am animating a UITableView. I want the table view to slide open like this:

http://www.youtube.com/watch?v=XIGJLbiRsXE

However, it opens like this:

http://www.youtube.com/watch?v=UJUX-ILCB_0

Notice how the table cells themselves are animating. How can I stop this from happening?

I am using autolayout. The code is thus:

[theView addSubview:theTable];
[theTable reloadData];
[theTable invalidateIntrinsicContentSize];
[UIView animateWithDuration:.33 animations:^{
    [theView layoutIfNeeded];
 }];

Other details, which may or may not matter:

  • The table view's parent is a scrollView

  • I have overridden the intrinsicContentSize of the table view to return the height of all the cells in the table view, so the table view will not scroll

  • I am changing the datasource of the table view before displaying it

Sinnard answered 29/4, 2013 at 17:34 Comment(0)
K
14

I had a similar problem and was able to stop the animation on the UITableViewCell with the UIView performWithoutAnimation: method.

Use the tableView:willDisplayCell:forRowAtIndexPath: UITableViewDelegate method to get a reference to the cell before it is shown. Then, within the performWithoutAnimation: block, call layoutIfNeeded on the cell object to give it a chance to layout its subviews:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [UIView performWithoutAnimation:^{
        [cell layoutIfNeeded];
    }];
}
Knownothing answered 19/10, 2014 at 20:0 Comment(0)
W
2

It might be too late to answer this question but the problem in these kind of cases generally lies in the animation block capturing all the pending layouts scheduled in the next run loop.

The solution that i use is. I call layoutIfNeeded before the animation (before setting or invalidating any constraints) and then inside the animation block.

In your case it will something like this,

[theView addSubview:theTable];
[theTable reloadData];
[theView layoutIfNeeded];
[theTable invalidateIntrinsicContentSize];
[UIView animateWithDuration:.33 animations:^{
    [theView layoutIfNeeded];
 }];
Watchband answered 2/1, 2016 at 14:0 Comment(0)
A
1

Have you considered animating instead an opaque subview that is positioned above the table view?

[theView addSubview:theTable];
[theTable reloadData];

UIView *subview = [[UIView alloc] initWithFrame:theTable.frame];
subview.backgroundColor = [UIColor whiteColor];
[theView addSubview:subview];

[UIView animateWithDuration:0.33 animations:^{
    subview.frame = CGRectMake(subview.frame.origin.x, subview.frame.size.height, subview.frame.size.width, 0.0);
}];
Argyrol answered 29/4, 2013 at 19:20 Comment(1)
I don't think this would work in my case, as the subviews below the table need to animate up and down with the table as well.Sinnard
S
0

Try laying out the table first, before you call [theView layoutIfNeeded] inside the animation block. Ideally you could layout piecemeal and for that 0.33 seconds you may get a scroll bar on the table but the goal is to get the table cell layout changes outside of the animated block.

Slain answered 30/4, 2013 at 1:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.