Ios UITableView,在重新加载单元格后向上滚动时动态单元格高度跳跃
我有一个表格视图,每个单元格都有自己的高度,因此不适合使用Ios UITableView,在重新加载单元格后向上滚动时动态单元格高度跳跃,ios,objective-c,swift,uitableview,Ios,Objective C,Swift,Uitableview,我有一个表格视图,每个单元格都有自己的高度,因此不适合使用行高。相反,现在我使用的是let indexSet=NSIndexSet(index:10),以及self.tableView.estimatedRowHeight=75。这意味着它调用单元格上的sizehatfits函数来确定其“高度”。这一切都很好 问题是当你重新加载屏幕上的单元格时。例如,向下滚动显示单元格10,然后重新加载单元格10,效果良好。但是,当您开始向上滚动时,经过您已经看到的单元格,它会恢复为每个单元格的估计亮度,完全不
行高
。相反,现在我使用的是let indexSet=NSIndexSet(index:10)
,以及self.tableView.estimatedRowHeight=75
。这意味着它调用单元格上的sizehatfits
函数来确定其“高度”。这一切都很好
问题是当你重新加载屏幕上的单元格时。例如,向下滚动显示单元格10,然后重新加载单元格10,效果良好。但是,当您开始向上滚动时,经过您已经看到的单元格,它会恢复为每个单元格的估计亮度,完全不考虑sizehattfits
,因此在滚动时会跳转。我不可能给出一个准确的或“足够好”的估计光线,这样这种跳跃就不会被注意到,因为我的细胞将能够显示一行文本或一幅完整的图像——大小上的巨大差异
我在这里展示了这种效果:
我在这方面做了很多不同的尝试,使用了RowatineXpath的高度和RowatineXpath的估计重量的混合。。等我试过关于StackOverflow的各种建议。似乎什么都不管用
我附上了一个非常简单的示例项目,您可以自己尝试:
值得注意的是,如果重新加载时单元格不在视图中,则不会发生这种情况。如果它高于或低于当前滚动点,则一切正常。我也遇到了同样的问题,我的表工作正常,直到重新加载tableview。所以我找到了一个解决方案,只使用rowHeight而不是估计的height。如果你有不同的身高。因此,请提供完整的代码,所以我将提供一个解决方案。我有一个类似instagram页面的手机。我通过了高度FORROW方法中的计算高度,该方法工作良好。但在这种情况下,估计的高度并不合适。如果您使用下面的代码,它可以正常工作。请试一试
self.tableView.rowHeight = 75 //it will be your dynamic height
//self.tableView.estimatedRowHeight = 75
如果您混淆了计算每个单元格行的高度,只需发布示例,我将提供解决方案。如果可以的话
谢谢嗯。。。这是一个很难处理的问题 让我们看看facebook。他们的时间表也有同样的问题,他们最终在某种网络视图中完成了这项工作 我有一个类似的问题与某种时间线,使用自动行高,并有这个问题。首先要解决的是将
estimatedHeight
设置为尽可能接近平均单元格高度。这很难处理,因为您可能有文本(高度50)或图像+文本(高度1500)。接下来要改进的是实现estimatedHeight for IndexPath
,它基本上会为不同的IndexPath返回不同的估计高度
此后,出现了许多其他解决方案,但这是最接近的解决方案,具有可变高度(巨大差异)。这种行为似乎是一个错误,如果不是因为其他原因,它不再在iOS 9上重现的话。我相信这不是什么安慰 正如@NickCatib所说,这一问题主要源于估算不准确。在iOS 8上,您所能做的最好的事情就是改进估计。许多人推荐的一种技术是在
willDisplayCell
中缓存高度,并在后续调用estimatedRowHeightAtIndexPath
时使用它们
您可能可以通过不做任何事情来让UITableView
放弃其缓存来缓解这种行为,比如直接使用cellforrowatinexpath
修改单元格中的内容,而不是在屏幕上使用重新加载。但是,如果您确实需要更改单元格的高度,则这不会有帮助
我恐怕要说的是,这个bug在表视图中很难修复,因为您无法控制布局。通过在失效期间更改
contentOffsetAdjustment
,可以更容易地在子类UICollectionViewFlowLayout
中解决该错误,尽管这可能并不十分容易。我也遇到了这个问题,并使用了一个解决方案,因此我现在无法找到该解决方案。如果我这样做,我会添加链接。以下是解决方案:
问题在于表视图没有正确估计行的高度。要修复此问题,请先将高度缓存在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;
}
}
在iOS 13.5.1中:
我有一个tableView,其中包含4种类型的单元格,它们都具有不同的动态高度。
我在这里遵循了公认的解决方案,但为了解决跳跃效应,我需要在重新加载表视图时添加更多内容:
根据已接受的答案,我添加了以下代码:
声明此变量
var allCellHeights = [IndexPath : CGFloat]()
然后添加两种方法:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.allCellHeights[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return self.allCellHeights[indexPath] ?? UITableView.automaticDimension
}
现在,我必须在重新加载tableview时添加额外的代码:
let contentOffset = self.tableView.contentOffset
self.tableView.reloadData()
self.tableView.layoutIfNeeded()
self.tableView.setContentOffset(contentOffset, animated: false)
同时检查以下答案:不要只是发布一个项目,然后让人们了解你的问题。用相关代码更新您的问题。我在
UICollectionView
中遇到了类似的问题。两者是相似的,因此类似的方法可能会有所帮助。当您使用UITableViewAutomaticDimension
时,似乎有一个bug。请参阅和问题的其他答案。这是正确的答案:返回正确的值EstimatedRowheeghtAtIndexPath:
完全可以解决此问题。我非常爱你。这立刻解决了我的问题。作为一个有趣的副作用,缓存单元格高度也会使滚动速度非常快,所以我真的推荐cachingfilly!谢谢@不客气!我不会因为这个答案而受到表扬,我在别的地方找到了它,但是再也找不到它的链接了。也欢迎来到SO!