Changing compositional layout on UICollectionView makes cells disappear

Viewed 389

I have a problem while switching compositional layouts to activate and deactivate orthogonal scrolling makes the cells disappear.

Here is a video:

Cells disappearing

I use exactly the same layout except for orthogonal scrolling:

section.orthogonalScrollingBehavior = hasOrthogonalScroll ? .groupPagingCentered : .none

And I switch the layout with this line:

collectionView.setCollectionViewLayout(layout, animated: true)

The first switch works, but when I switch back, cells disappear...

If someone can tell me what I do wrong, it would be much appreciated...

Here is the full code copy and paste in the ViewController file of a new project:

class ViewController: UIViewController, UICollectionViewDelegate {

    var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionLayout(hasOrthogonalScroll: false))
        collectionView.delegate = self
        collectionView.frame = view.bounds
        collectionView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        view.addSubview(collectionView)
        
        setupDataSource()
    }

    private func collectionLayout(hasOrthogonalScroll: Bool) -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)

        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.2))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = hasOrthogonalScroll ? .groupPagingCentered : .none

        return UICollectionViewCompositionalLayout(section: section)
    }
    
    enum Section {
        case main
    }
    
    private var dataSource: UICollectionViewDiffableDataSource<Section, Int>!

    private func setupDataSource() {
        let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { (cell, indexPath, identifier) in
            var configuration = cell.defaultContentConfiguration()
            configuration.text = identifier.description
            
            cell.contentConfiguration = configuration
            
            var backgroundConfiguration = cell.backgroundConfiguration
            backgroundConfiguration?.backgroundColor = .secondarySystemBackground
            backgroundConfiguration?.cornerRadius = 8
            backgroundConfiguration?.backgroundInsets = .init(top: 4, leading: 4, bottom: 4, trailing: 4)
            
            cell.backgroundConfiguration = backgroundConfiguration
        }
        
        dataSource = UICollectionViewDiffableDataSource<Section, Int>(collectionView: collectionView) { collectionView, indexPath, identifier in
            collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: identifier)
        }
        
        var snapshot = NSDiffableDataSourceSnapshot<Section, Int>()
        snapshot.appendSections([.main])
        snapshot.appendItems(Array(1...100))
        dataSource.apply(snapshot, animatingDifferences: false)
    }
    
    var hasOrthogonalScroll = false
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.deselectItem(at: indexPath, animated: true)
        
        hasOrthogonalScroll.toggle()
        let layout = collectionLayout(hasOrthogonalScroll: hasOrthogonalScroll)
        collectionView.setCollectionViewLayout(layout, animated: true) 
    }
}
0 Answers
Related