在滚动时保持UICollectionView中的滚动位置
问题描述:
我有一个UICollectionView
,有一个类似于视图的聊天 - 消息显示在最新的底部。随着用户向上滚动,它会加载之前的消息并更新集合视图。我试图保持UICollectionView
的内容偏移量,因为添加了新的数据,但我无法使其正常工作。在滚动时保持UICollectionView中的滚动位置
这就是我目前所面对的:
// First find the top most visible cell.
if let topCellIndexPath = collectionView.indexPathsForVisibleItems.sorted().first,
let topCell = collectionView.cellForItem(at: topCellIndexPath),
let topCellLayout = collectionView.layoutAttributesForItem(at: topCellIndexPath) {
// Save the y position of the top cell.
let previousTopCellY = topCellLayout.frame.origin.y
// Perform updates on the UICollectionView without animation (ignore the fact it says adapter)
adapter.performUpdates(animated: false) { [weak self] completed in
if let strongSelf = self,
let topCellNewIndexPath = strongSelf.collectionView.indexPath(for: topCell),
let newTopCellLayout = strongSelf.collectionView.layoutAttributesForItem(at: topCellNewIndexPath) {
// Calculate difference between the previous cell y value and the current cell y value
let delta = previousTopCellY - newTopCellLayout.frame.origin.y
// Add this to the collection view content offset
strongSelf.collectionView.contentOffset.y += delta
}
}
}
这似乎并不工作,有时更新后无法获得细胞的indexPath。
编辑 基于@Arkku的回答这个工程。虽然有一个小闪烁。
let previousContentSize = collectionView.contentSize.height
adapter.performUpdates(animated: false) { [weak self] completed in
if let strongSelf = self {
let delta = strongSelf.collectionView.contentSize.height - previousContentSize
strongSelf.collectionView.contentOffset.y += delta
}
}
答
正如我在前面的评论,它可能是更好地得到来自contentSize
的delta
而不是特定的细胞来源。一个建议根据您自己的版本:
let previousContentHeight = collectionView.contentSize.height
adapter.performUpdates(animated: false) { [weak self] completed in
guard let strongSelf = self else { return }
let delta = strongSelf.collectionView.contentSize.height - previousContentHeight
strongSelf.collectionView.bounds.origin.y += delta
}
尝试从内容大小,而不是细胞来源'delta'。 – Arkku
@Arkku这工作,根据您的答案更新问题与我的解决方案。但是,有一个轻微的闪烁,它不完全平滑。我认为抵消不是100%正确的... – Tometoyou