Here is a screenshot of the app:
And here follows the code: it's a view controller with a collection view with plain list layout and a diffable data source.
It has 1 section with 2 rows.
The 1st row's content configuration is UIListContentConfiguration.cell(), and it has some text.
The 2nd row has an empty content configuration instead.
As you can see, if you run the app, the separator insets are different for the two rows.
Did I make a mistake?
If this is expected behavior instead, is there an easy fix?
import UIKit
class ViewController: UIViewController {
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<String, String>!
var snapshot: NSDiffableDataSourceSnapshot<String, String> {
var snapshot = NSDiffableDataSourceSnapshot<String, String>()
snapshot.appendSections(["main"])
snapshot.appendItems(["one", "two"])
return snapshot
}
override func viewDidLoad() {
super.viewDidLoad()
configureHierarchy()
configureDataSource()
}
func configureHierarchy() {
collectionView = .init(
frame: view.bounds,
collectionViewLayout: createLayout()
)
view.addSubview(collectionView)
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
func createLayout() -> UICollectionViewLayout {
return UICollectionViewCompositionalLayout { section, layoutEnvironment in
let config = UICollectionLayoutListConfiguration(appearance: .plain)
return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
}
}
func configureDataSource() {
let firstCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
var contentConfiguration = UIListContentConfiguration.cell()
contentConfiguration.text = "Hello"
cell.contentConfiguration = contentConfiguration
}
let secondCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
}
let emptyCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
}
dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
switch itemIdentifier {
case "one":
collectionView.dequeueConfiguredReusableCell(using: firstCellRegistration, for: indexPath, item: itemIdentifier)
case "two":
collectionView.dequeueConfiguredReusableCell(using: secondCellRegistration, for: indexPath, item: itemIdentifier)
default:
collectionView.dequeueConfiguredReusableCell(using: emptyCellRegistration, for: indexPath, item: itemIdentifier)
}
}
dataSource.apply(self.snapshot, animatingDifferences: false)
}
}
Xcode 15.4, iPhone 15 Pro simulator, iOS 17.5, MacBook Air M1 8GB, macOS 14.5.
The default behavior for list separators is to align to the leading edge of text in the cell above them. In your example, because the second cell has no text, the separator below that cell is just following the default inset.
You can manually customize the behavior of each item's separator using the itemSeparatorHandler
on the UICollectionLayoutListConfiguration
: https://developer.apple.com/documentation/uikit/uicollectionlayoutlistconfiguration/3727737-itemseparatorhandler