📰
CompositionalLayoutのヘッダ領域を完全に無くす方法
次のようなコードで、2つのセクションを持つCompositionalLayoutを作ります。
enum Section: Int {
case groupA
case groupB
}
struct Item: Identifiable, Hashable {
let id: UUID = UUID()
}
class ViewController: UIViewController {
let configuration: UICollectionLayoutListConfiguration = {
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.headerMode = .none
return configuration
}()
lazy var listLayout: UICollectionViewCompositionalLayout = .list(using: configuration)
lazy var collectionView = UICollectionView(
frame: .null,
collectionViewLayout: listLayout
)
lazy var dataSource = UICollectionViewDiffableDataSource<Section, Item>(
collectionView: collectionView,
cellProvider: { [unowned self] (collectionView, indexPath, item) in
collectionView.dequeueConfiguredReusableCell(
using: cellRegistration,
for: indexPath,
item: item
)
}
)
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Item>(handler: { (cell, indexPath, item) in
var contentConfiguration = cell.defaultContentConfiguration()
contentConfiguration.text = "\(indexPath)"
cell.contentConfiguration = contentConfiguration
})
override func loadView() {
view = collectionView
}
override func viewDidLoad() {
super.viewDidLoad()
_ = dataSource
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.groupA, .groupB])
snapshot.appendItems([.init()], toSection: .groupA)
snapshot.appendItems([.init()], toSection: .groupB)
dataSource.apply(snapshot)
}
}
すると、headerMode
がnone
であるにも関わらずセクションの間が微妙に空いてしまいます。
つまり、headerModeはヘッダ領域を完全に無くすのではなく余白は適度に開けつつ何も表示しないオプションであることが分かります。
このヘッダ領域を完全に無くすには、supplementaryViewProvider
を使って自分でヘッダビューを提供し、そのサイズを0にします。
configuration.headerMode = .supplementary
...
let headerRegistration = UICollectionView.SupplementaryRegistration<UICollectionReusableView>(
elementKind: UICollectionView.elementKindSectionHeader,
handler: { (supplementaryView, elementKind, indexPath) in
supplementaryView.frame.size.height = 0
}
)
...
dataSource.supplementaryViewProvider = { [unowned self] (collectionView, elementKind, indexPath) in
collectionView.dequeueConfiguredReusableSupplementary(
using: headerRegistration,
for: indexPath
)
}
これで完全にヘッダ領域を無くすことができました。
Discussion