czwartek, 1 października 2015

UITableView animations cautionary tale

I want this to be a quick post to make people aware of a certain bug/feature in iOS UITableView. For example Skype people are either not aware of it, or just don't know how to fix that. My guess is that they are aware, as you can see that the cells are fading in as if they wanted to hide that:

Even though the cells are being faded in you can see as the top cells get recycled and transformed/animated from one size to another.

Why does it happen ? When you change the height constraint on the UITableView and call layoutIfNeeded in an animation block, it'll also update the UITableView cell's contents frames in the very same animation block

Because UITableView recycles cells, the message bubble could be 30 points in width before it got recycled and you set it to 100 points width and called layoutIfNeeded in a block high in hierarchy. That's why we see it animate from 30 points to 100 points! Of course it won't happen if all contents in a UITableViewCell have a constant size. It would of course happen too without recycling, as it would animate from the initial xib/storyboard size to the dynamically calculated size.

I had a pleasure to listen one of Marin Todorov's talks on animations yesterday and I think one of the demo's suffered, or would suffer from this problem - the contents of UITableViewCells being animated as the UITableView animates. I created a quick project to duplicate his demo and this is the result, when the square's width in the UITableViewCell is random:

Take a close look at the bottom cells as they're being animated from their old size to the new size. 

What to do now ?!

I found two good solutions to this problem:

• Disable animations for the views that suffer to this problem. It's kind of a hack, but it works. For this example, I've created a dontAnimate UIView subclass and set it as the blue rectangles in the demo.

• Animating contentInset and contentOffset instead.

Did you ever have that problem ? How did you fix it ? Is that a bug ? I invite you for a discussion :)