I think you should not use beginUpdate
/endUpdates
methods and perform animations manually before calling reloadData
. The final state of cells (after animation) are defined with datasource. Here's an example of animation in tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndexPath = indexPath;
[UIView animateWithDuration:1 animations:^{
// move down cells which are below selected one
for (UITableViewCell *cell in tableView.visibleCells) {
NSIndexPath *cellIndexPath = [tableView indexPathForCell:cell];
if (cellIndexPath.row > indexPath.row) {
CGRect frame = cell.frame;
frame.origin.y += kTargetHeight - tableView.rowHeight;
cell.frame = frame;
}
}
// expand selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect frame = cell.frame;
frame.size.height = kTargetHeight;
cell.frame = frame;
} completion:^(BOOL finished) {
[tableView reloadData]; // commit final state
}];
}
The final state of selected cell:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath isEqual:_selectedIndexPath]) {
return kTargetHeight;
}
return tableView.rowHeight;
}