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?