0

I have a UICollectionView of UICollectionView, so each row has 1 cell with a UICollectionView inside.

I want that the selected row always move to the top of the my CollectionView, currently the selected row is centered inside the CollectionView.

Does someone know how to achieve this ? I tried to play with a custom UICollectionViewFlowLayout but without success...

What I have below (grey box is my CollectionView): What I have below (grey box is my CollectionView)

What I would like to have (grey box is my CollectionView): What I would like to have (grey box is my CollectionView)]2

CloudInSky
  • 13
  • 1
  • 5

2 Answers2

0

You can scroll to the selected item using This:

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

The some of the last items will not goes to top because it won't have more space to move top so for fix that you have to calculate & set tableview bottom inset.

urvashi koladiya
  • 168
  • 1
  • 11
0

Thanks to @urvashikoladiya's help

For those who might be interested in the solution, I need to dispatch the scrollToItem function's call because my UICollectionView child cell is already animating so I have to be sure the animation is finish before asking the scroll position to top.

There might be a more elegant way to do it, but I haven't found

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)
            }
        }
    }
}
CloudInSky
  • 13
  • 1
  • 5