Reputation: 1011
I'm looking to be able to expand / contract all the cells in a UITableView while maintaining the current position and having the change animate the height change. Essentially it should look like the current cells in view are expanding / contracting and the scroll position stays the same.
I'm able to expand / contact the cells by having 2 states with different heights and calling
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
And I've tried to maintain the same position by doing (not 100% this calculation is correct):
//calculate the new position it should scroll to based on new cell height
CGFloat posFromTop = self.tableView.contentOffset.y;
CGFloat newDistance = 0;
if(expandedState)
{
CGFloat cellsFromTop = posFromTop / kExpandedCellHeight;
newDistance = cellsFromTop * kCollapsedCellHeight;
}
else
{
CGFloat cellsFromTop = posFromTop / kMGLCollapsedCellHeight;
newDistance = cellsFromTop * kMGLExpandedCellHeight;
}
}
//reload section
[self.tableView setContentOffset:CGPointMake(0, newDistance) animated:YES];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
While this seems to kind of work, it doesn't keep position as it animates, it flashes white and so it's choppy and doesn't look like the tableView is staying still during the reloading.
Anyone have a method for smoothly animating the height of all cells while keeping the same position?
Upvotes: 2
Views: 2927
Reputation: 619
Try replacing
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation: UITableViewRowAnimationAutomatic];
with
[self.tableView beginUpdates];
[self.tableView endUpdates];
The latter will take the current cells and update their sizes. Reloading the sections with automatic animation was likely using a fade animation which generates new cells at the new heights and fades between the existing ones and the new ones, which was probably not what you wanted.
Upvotes: 2
Reputation: 8484
You can probably find out how much time it takes to perform the first collapse-animation, let's say it takes exactly 1 second. Then I think you'll be able to say something like this:
[UIView animateWithDuration:1.0 animations:^{
[self.tableView setContentOffset:CGPointMake(0, newDistance) animated:NO];
}];
This will perform an animation over 1 second, where your tableView starts at current contentOffset, and ends up with the contentOffset you want. I've never used UITableViewRowAnimationAutomatic
, or animation for tableView at all for that matter, but maybe you could try some other values as well.
Actually, you might be able to fit both those actions into the same animation, if you know what I mean. Which would also give you control over the duration of everything. I don't know if that'll work, I can't test it right now, but that would look something like this:
[UIView animateWithDuration:1.0 animations:^{
[self.tableView setContentOffset:CGPointMake(0, newDistance) animated:NO];
[self.tableView setRowHeight:newHeight];
}];
I doubt that particular method actually exist, but I'm sure you get what I'm talking about, and will find it if there's something similar out there. Maybe even with nil
as animation-parameter in your original call.
(There's also something called beginUpdates
and endUpdates
you could look into if this isn't working, but I'm not sure that can change the height)
Upvotes: 0