I am struggling with the following issue: I have an UICollectionView with an UICollectionViewCompositionalLayout and two sections. The first section has set orthogonalScrollingBehavior to .continues and has horizontal scrolling. The second section has vertical scrolling.

When I select an element, I want to toggle the layout of the first section from horizontal to vertical and from . The layout change should be animated withself.collectionView.setCollectionViewLayout(layout, animated: true) The animation works with iOS 13 but not with iOS 14 (tested on all versions including iOS 14 beta 2).

In iOS 14 the animation of the first section is not working if the layout is changed from a horizontal layout to a vertical layout. The animation is broken / not visible and the cells are not displayed. The first section seems to be empty after the layout change is completed and the cells are not shown. When I scroll the collection view to the bottom and back to the top the cells appear again. If the layout of the first section is changed from vertical to horizontal then the animation is working also on iOS 14 but not when the layout of the section is changed from horizontal to vertical.

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
    var isSectionVerticalLayout = false
    var collectionView: UICollectionView! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayoutDiffSection())
        collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "customCellId")
        collectionView.dataSource = self
        collectionView.delegate = self
        
        view.addSubview(collectionView)
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCellId", for: indexPath)
        cell.backgroundColor = UIColor(red: .random(in: 0...1),
                                       green: .random(in: 0...1),
                                       blue: .random(in: 0...1),
                                       alpha: 1.0)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        isSectionVerticalLayout = !isSectionVerticalLayout
        let layout = createLayoutDiffSection()

        self.collectionView.setCollectionViewLayout(layout, animated: true) { (finished) in
        }
    }
    
    func createLayout(isVerticalLayout: Bool) -> NSCollectionLayoutSection {
        
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
        
        let groupHeight = NSCollectionLayoutDimension.fractionalWidth(0.5)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                               heightDimension: groupHeight)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 2)
        
        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20)
        
        if isVerticalLayout == false {
            section.orthogonalScrollingBehavior = .continuous
        }
        return section
    }

    
    func createLayoutDiffSection() -> UICollectionViewLayout {
        let layout = UICollectionViewCompositionalLayout { (sectionIndex: Int,
            layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
            
            if sectionIndex == 0 {
                return self.createLayout(isVerticalLayout: self.isSectionVerticalLayout)
            }
            else {
                return self.createLayout(isVerticalLayout: true)
            }
        }
        return layout
    }
}

Any idea how to fix this (workaround) or if this is a bug in iOS 14?

0

There are 0 answers