如何将选定的行移动到 UICollectionView 的顶部

How to move selected row to the top of UICollectionView

我有一个 UICollectionView 的 UICollectionView,所以每一行都有 1 个单元格,里面有一个 UICollectionView。

我希望所选行始终移动到我的 CollectionView 的顶部,当前所选行在 CollectionView 中居中。

有人知道如何实现吗? 我尝试使用自定义 UICollectionViewFlowLayout 但没有成功...

下面是我的(灰色框是我的 CollectionView):

我想要的(灰框是我的CollectionView): ]2

您可以使用以下方法滚动到所选项目:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
     self.collectionView.scrollToItem(at: indexPath, at: .top, animated: true)
}

最后的一些项目不会移到顶部,因为它没有更多 space 移动到顶部,因此为了解决这个问题,您必须计算并设置 tableview 底部插图。

感谢@urvashikoladiya 的帮助

对于那些可能对该解决方案感兴趣的人,我需要调度 scrollToItem 函数的调用,因为我的 UICollectionView 子单元格已经在设置动画,所以我必须确保在询问滚动位置到顶部之前动画已经完成。

可能有更优雅的方法,但我还没有找到

class MyCollectionViewCell: UICollectionViewCell,UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
        if let nextIndexPath = context.nextFocusedIndexPath {
        delegate?.selectedRow(cell: self)            
    }
}

class MainCollectionView: UICollectionViewController, UICollectionViewDelegateFlowLayout, CollectionViewCellDelegate {

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MyCollectionViewCell
        cell.delegate = self
        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, canFocusItemAt indexPath: IndexPath) -> Bool {
        return false
    }

    func selectedRow(cell: MyCollectionViewCell) {
        if let indexPath = collectionView.indexPath(for: cell) {
            DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(5)) {
                self.collectionView.scrollToItem(at: indexPath, at: .top, animated: true)
            }
        }
    }
}