2015-09-07 110 views
12

我有一个表格视图,每个单元格都有自己的高度,因此不适合使用rowHeight。相反,现在我正在使用let indexSet = NSIndexSet(index: 10)self.tableView.estimatedRowHeight = 75。这意味着它调用单元上的sizeThatFits函数来确定它的高度。这一切运作良好。UITableView具有动态单元高度在重新加载单元格后向上滚动时跳跃

问题是当你重新加载屏幕上的单元格时。例如向下滚动以显示单元10,然后重新加载单元10,工作正常。但是当你开始回滚时,通过你已经看到的单元格,它将恢复到每个单元格的估计的高度,完全忽略了sizeThatFits,所以当你滚动时跳转。我不可能给出一个准确或“足够好”的估计的高度,这样跳跃就不会明显,因为我的细胞能够显示文本行或完整图像 - 尺寸。

我这里显示这个效果:

https://vid.me/edgW

我做了这许多不同的尝试,使用heightForRowAtIndexPath,estimatedHeightForRowAtIndexPath ..等的混合物。我已经试过各种片关于StackOverflow的建议。似乎没有任何工作。

我们已经附上一个非常简单的示例项目,在那里你可以自己尝试:

https://www.dropbox.com/s/8f1rvkx9k23q6c1/tableviewtest.zip?dl=0

  1. 运行项目。
  2. 滚动到单元格10在视图中。
  3. 等待长达5秒的单元重新加载(它变成紫色)。
  4. 向上滚动。

值得注意的 - 这并没有发生如果当它重新加载该小区不是在视图中。如果它高于当前滚动点以下的,则一切按预期工作。

+2

不要只发布一个项目,并要求人们找出您的问题。用相关的代码更新你的问题。 – rmaddy

+0

我有一个'UICollectionView'类似的问题。这两者是相似的,所以类似的方法可能对此有所帮助。发布[答案在这里](https://stackoverflow.com/a/45361410/6744473) – shoe

回答

15

这种行为似乎是一个错误,如果没有其他原因,它不再可以在iOS 9上重现。我相信这并没有太多的安慰。

这个问题主要来自于有一个不准确的估计,就像@NickCatib所说。在iOS 8上可以做的最好的事情就是改善评估。许多人建议的技术是在willDisplayCell中缓存高度,并在后续调用estimatedRowHeightAtIndexPath时使用它们。

您可以通过不做任何事情来让UITableView放弃其缓存,例如通过直接使用cellForRowAtIndexPath修改单元格中的内容,而不是在屏幕上使用重新加载。但是,如果您实际需要更改单元格的高度,这将无济于事。

我不敢轻易在表格视图中修正该bug,因为您无法控制布局。通过在失效期间更改contentOffsetAdjustment,该错误可以更容易地在子类UICollectionViewFlowLayout中解决,尽管这可能不是非常容易。

+0

这是正确的答案:返回适当的值'estimatedRowHeightAtIndexPath:'完全使这个问题消失。 – MarcWan

+0

我非常爱你。这立即解决了我的问题。作为一个有趣的副作用,缓存单元高度也使得滚动*真的很快,所以我真的推荐缓存 – Sirens

-1

我正面临同样的问题,我的表工作正常,直到tableview重新加载。所以我找到了一个解决方案,只使用rowHeight没有估计的高度。另外如果你有不同的身高。所以请提供完整的代码,以便我提供一个解决方案。我有一个像Instagram页面的单元格。我正在通过计算高度在高度运行方法,它工作正常。但估计高度在这种情况下不能正常工作。如果你使用下面的代码,它工作正常。请尝试。

self.tableView.rowHeight = 75 //it will be your dynamic height 
//self.tableView.estimatedRowHeight = 75 

如果你混淆来计算每个单元格的行的高度,只需发布​​样本我将提供解决方案。如果我可以 谢谢

0

呃......这是一个棘手的问题来处理。

让我们来看看Facebook。他们在他们的时间表上遇到了同样的问题,他们最终以某种网络视图的方式做了这件事。

我有一个类似的问题,某种时间轴,使用自动行高度,并有这个问题。首先要解决的是设置estimatedHeight尽可能接近平均细胞高度。这很难处理,因为你可能有文字(高度50)或图像+文字(高度1500)。接下来要做的就是改进estimatedHeight forIndexPath,它基本上为不同的索引路径返回不同的估计高度。

之后,有很多其他的解决方案,但这是尽可能最接近的,因为它可以与可变高度(巨大的差异)。

3

我也有这个问题,并使用了我现在无法找到的SO的解决方案。如果我这样做,我会添加链接。以下是解决方案:

问题是表视图没有正确估计行高度。要修复它,请先将高度缓存在willDisplayCell中,然后再次使用该高度。

代码

在viewDidLoad中:

heightAtIndexPath = [NSMutableDictionary new]; 


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSNumber *height = @(cell.frame.size.height); 
    [heightAtIndexPath setObject:height forKey:indexPath]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    return UITableViewAutomaticDimension; 
} 

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    if([heightAtIndexPath objectForKey:indexPath]) { 
     return [[heightAtIndexPath objectForKey:indexPath] floatValue]; 
    } else { 
     return UITableViewAutomaticDimension; 
    } 
} 
+1

最后!谢谢!! –

+0

@ kam.voick欢迎您!我不会拿信用来回答这个问题,但我发现它在其他地方,但无法找到它的链接了。也欢迎SO! –

相关问题