调用deleteRowsAtIndexPaths时,具有自定义单元格的UITableView变得不稳定

我有一个带自定尺寸单元格的UITableView。 表包含1个部分和一些行。 我有一些行说30,我想在didSelectRowAtIndexPath期间删除行。

当我删除tableview底部附近可用的行(例如第28行)时,第28行之前的行会改变它们的位置,并且由于deleteRowsAtIndexPaths而导致动画deleteRowsAtIndexPaths 。 有关详细信息,请参阅附带的GIF。

使用帧删除动画构造的单元格

自动resize单元删除动画

  - (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]; } 

这种不稳定的动画只发生在自定尺寸单元格中,而不是由用框架构造的单元格发生。 任何帮助将不胜感激。

编辑1:问题是内容偏移和内容大小。 让我们说表格视图中的每个单元格的高度为50.因此对于20个单元格,内容大小约为1000.让我们将设备高度视为200,将宽度视为100.因此内容大小将为100,1000。 当我滚动到tableview底部时,内容偏移变为0,800。 当我现在删除一行时,内容大小将更新为100,950,内容偏移现在会尝试根据内容大小的变化调整为新值。 所以这会导致混乱。

生涩的动画是由于您的细胞估计的不正确高度造成的。 因此,您需要在表视图控制器中实现estimatedRowHeight并返回保存的高度。 您可以将willDisplayCell tableView委托方法中先前加载的单元格高度保存为cell.frame.size.height中的cell.frame.size.height

 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 } } 

[tableView beginUpdates];删除代码放在[tableView beginUpdates];[tableView endUpdates];

像这样更新您的方法并尝试:

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]; }