CloudInSky
CloudInSky

Reputation: 23

Apple TV UICollectionView Compositional Layout cant scroll to top with vertical scrolling

I'm creating a Netflix like app on tvOS, here is my compositional layout that I use with my collectionView.

private func createLayout() -> UICollectionViewCompositionalLayout {
    return UICollectionViewCompositionalLayout { (section, _) -> NSCollectionLayoutSection? in
        // item
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                              heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
        
        // group
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/5),
                                               heightDimension: .estimated(350))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
        
        // section
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .groupPaging
        
        
        let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                                heightDimension: .estimated(UIFont(name: "MyFont", size: 36)!.lineHeight))
        let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
            layoutSize: headerSize,
            elementKind: "SectionHeader",
            alignment: .top)
        
        section.boundarySupplementaryItems = [sectionHeader]
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 30, trailing: 0)
        
        return section
    }
}

So:

I'm expecting to have the following behavior when scrolling:

Horizontal scrolling:

Before focus shifts
--------------------------
| vA   vB   vC   vD   vE |
|[v1]  v2   v3   v4   v5 |
| vU   vW   vX   vY   vZ |
--------------------------

After focus shifts
--------------------------
| vA   vB   vC   vD   vE |
|[v2]  v3   v4   v5   v6 |
| vU   vW   vX   vY   vZ |
--------------------------

Vertical scroll:

Before focus shifts
--------------------------
|[vA]  vB   vC   vD   vE |
| v1   v2   v3   v4   v5 |
| vU   vW   vX   vY   vZ |
--------------------------

After focus shifts
--------------------------
|[v1]  v2   v3   v4   v5 |
| vU   vW   vX   vY   vZ |
| vF   vG   vH   vI   vJ |
--------------------------

Thanks to section.orthogonalScrollingBehavior = .groupPaging the horizontal scrolling is working as expected. (I've put 1 item per group to achieve this)

But I'm going crazy with the vertical scroll, I'm not able to achieve it as expected, the focused section still centered verticaly on the screen ! What I'm getting:

Before focus shifts
--------------------------
|[vA]  vB   vC   vD   vE |
| v1   v2   v3   v4   v5 |
| vU   vW   vX   vY   vZ |
--------------------------

After focus shifts
--------------------------
| vA   vB   vC   vD   vE |
|[v1]  v2   v3   v4   v5 |
| vU   vW   vX   vY   vZ |
--------------------------

After an other focus shifts
--------------------------
| v1   v2   v3   v4   v5 |
|[vU]  vW   vX   vY   vZ |
| vF   vG   vH   vI   vJ |
--------------------------

I've tried to play with the didUpdateFocusIn function without success

func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
    if let nextFocusedItemIndexPath = context.nextFocusedIndexPath {
        let section = nextFocusedItemIndexPath.section
        let sectionIndexPath = IndexPath(item: 0, section: section)
        collectionView.scrollToItem(at: sectionIndexPath, at: .top, animated: true)
    }
}

The collectionview is behaving strangely when using the didUpdateFocusIn function and I feel it's not the good way to perform what I'm expecting...

I've also try to play with the scrollViewWillEndDragging function without success

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: 
}

Everything that I tried looks like a hack and I can't believe Apple has not plan something for this use case, which is in my sense a common use case....

Upvotes: 0

Views: 57

Answers (0)

Related Questions