我有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
}
}
答案 0 :(得分:1)
正如我之前评论的那样,从delta
获取contentSize
而不是特定单元格的来源可能更好。基于您自己版本的建议:
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
}