How can I implement such layout using UICollectionView in UIKit? I need to add a new cell which height is greater than height of normal cell. AFAIK all cells in one row of UICollectionView must have the same height.
I think UICollectionViewCompositionalLayout will fit this scenario. It supports complex collection UI, like waterfall, nested cells, etc. And based on your requirements, it could be:
//Defining sections
enum Section: Int, Hashable {
case waterfall
case normal
}
The following is an explanation of the layouts above (all with insets):
waterfall: A section that has (width: 1.0, height: 0.4) ratio with collectionView frame. It contains a leading cell item with (width: 0.7, height: 1.0). And a pair of trailing vertical cells with (width: 0.3, height: 1.0). Each cell in this group will have (width: 1.0, height: 0.3) to their group
normal: A section that has (width: 1.0, height 0.2) ratio with collectionView frame. The layout will present two cells and each cell will get 0.5 width of collectionView.
UPDATED: I used UICollectionViewDiffableDataSource, configured it is simple:
//A struct to represent cell data. Notice: it has to conform Hashable
struct CellData: Hashable {
var title: String = ""
var identifier: UUID = .init()
init(_ title: String) {
self.title = title
}
}
//A dataSource represents collectionView data
var dataSource: UICollectionViewDiffableDataSource<Section, CellData>
Then append sections and items like you want:
//Simple text cell with a label
let cellRegistration = UICollectionView.CellRegistration<TextCell, CellData> { (cell, indexPath, identifier) in
cell.label.text = identifier.title
//Other configurations
}
dataSource = UICollectionViewDiffableDataSource<Section, CellData>(collectionView: collectionView, cellProvider: { collectionView, indexPath, item in
collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)
})
var snapshot = NSDiffableDataSourceSnapshot<Section, CellData>()
snapshot.appendSections([.waterfall])
let dummyWaterfallSection: [CellData] = [
.init("1"),
.init("2"),
.init("3"),
]
snapshot.appendItems(dummyWaterfallSection, toSection: .waterfall)
snapshot.appendSections([.normal])
let dummyNormalSection: [CellData] = [
.init("11"),
.init("22"),
.init("33"),
.init("44"),
.init("55"),
]
snapshot.appendItems(dummyNormalSection, toSection: .normal)
dataSource.apply(snapshot, animatingDifferences: false)
2
Answers
you can set that specific cell size in the below way:
I think
UICollectionViewCompositionalLayout
will fit this scenario. It supports complex collection UI, like waterfall, nested cells, etc. And based on your requirements, it could be:The following is an explanation of the layouts above (all with insets):
UPDATED: I used
UICollectionViewDiffableDataSource
, configured it is simple:Then append sections and items like you want:
Output: