Reputation: 1564
I have a UITableView with self sizing cells. Table contains 1 section and some rows. I have some rows say 30 and I want to delete row during didSelectRowAtIndexPath
.
When I delete a row available near the bottom of tableview (say 28th row ), the rows before 28th row changes their position and it causes jerky animation as a result of deleteRowsAtIndexPaths
. See attached gifs for more details.
Cells constructed with frame deletion animation
Auto Resizing cells Deletion animation
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return noOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell setCellText:[NSString stringWithFormat:@"Section = %li Row = %li", indexPath.section,indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
noOfRows--;
[tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:indexPath.row inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
}
This jerky animation happens only with self sizing cells and not with cells constructed with frame. Any help would be greatly appreciated.
EDIT 1: The problem is content offset and content size. Lets say each cell in table view has height of 50. So for 20 cells the content size would be around 1000. Lets consider device height as 200 and width as 100.So the content size will be 100,1000. When I scroll to bottom of the tableview content offset becomes 0,800. When I delete a row now the content size will be updated to 100, 950 and content offset now tries to adjust to new value as a result of change in content size. So this causes Jerkiness.
Upvotes: 2
Views: 697
Reputation: 414
The jerky animation is due to incorrect estimated heights of your cells. So you need to implement estimatedRowHeight
in your table view controller and return saved heights. You can save previously loaded cell heights in willDisplayCell
tableView delegate methods as cell.frame.size.height
in an array.
var estimatedHeights : [CGFloat] = []
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
{
if estimatedHeights.count > indexPath.row
{
return estimatedHeights[indexPath.row]
}
return 40
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
if estimatedHeights.count <= indexPath.row
{
estimatedHeights.append(cell.frame.height)
}
else
{
estimatedHeights[indexPath.row] = cell.frame.height
}
}
Also put your delete code within [tableView beginUpdates];
and [tableView endUpdates];
Upvotes: 4
Reputation: 4451
Update your method like this and try:
cellForRowAtIndexPath:
[cell setNeedsUpdateConstraints];
[cell layoutIfNeeded];
didSelectRowAtIndexPath:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
noOfRows--;
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:indexPath.row inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
Upvotes: 1