2017-04-17 68 views
0

我有一个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 
    } 
} 
+0

尝试从内容大小,而不是细胞来源'delta'。 – Arkku

+0

@Arkku这工作,根据您的答案更新问题与我的解决方案。但是,有一个轻微的闪烁,它不完全平滑。我认为抵消不是100%正确的... – Tometoyou

回答

1

正如我在前面的评论,它可能是更好地得到来自contentSizedelta而不是特定的细胞来源。一个建议根据您自己的版本:

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 
}