Reputation: 624
I am able to hide the bottom separator of the last row but unable to correctly indent based on my SwiftUI view in my collection view cell. How do I correctly indent it like the rest of my cells instead of being edge to edge?
I am aware you can set the indents manually in the list configuration but is there a better automatic way?
class ViewController: UIViewController {
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
private var headerRegistration: UICollectionView.SupplementaryRegistration<UICollectionViewCell>!
var items: [Item] = [
Item(title: "Item 1"),
Item(title: "Item 2"),
Item(title: "Item 3"),
Item(title: "Item 4"),
Item(title: "Item 5")
]
override func viewDidLoad() {
super.viewDidLoad()
registerHeader()
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.bottomAnchor.constraint(equalTo: addButton.topAnchor)
])
collectionView.register(UICollectionViewListCell.self, forCellWithReuseIdentifier: "cell")
configureDataSource()
applySnapshot()
}
func registerHeader() {
headerRegistration = .init(elementKind: UICollectionView.elementKindSectionHeader) {
(header, elementKind, indexPath) in
header.contentConfiguration = UIHostingConfiguration {
Button {
} label: {
Text("Header")
.frame(width: 100, height: 50)
.contentShape(.rect)
.buttonStyle(.bordered)
}
}
}
}
func createLayout() -> UICollectionViewLayout {
var listConfiguration = UICollectionLayoutListConfiguration(appearance: .grouped)
listConfiguration.headerMode = .supplementary
listConfiguration.itemSeparatorHandler = { [unowned self] (indexPath, sectionSeparatorConfiguration) in
var configuration = sectionSeparatorConfiguration
if indexPath.row == 0 {
configuration.topSeparatorVisibility = .hidden
} else if indexPath.row == items.count - 1 {
//Correctly the last row separator here?
configuration.bottomSeparatorVisibility = .hidden
}
return configuration
}
let layout = UICollectionViewCompositionalLayout.list(using: listConfiguration)
return layout
}
func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { (collectionView, indexPath, item) -> UICollectionViewCell? in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! UICollectionViewListCell
cell.contentConfiguration = UIHostingConfiguration {
HStack {
Image(systemName: "house")
.resizable()
.foregroundStyle(.gray)
.scaledToFit()
.padding()
.frame(width: 50, height: 50)
.background(.quaternary)
.cornerRadius(5)
.padding(.trailing, 5)
VStack(alignment: .leading) {
Text("Item name")
.lineLimit(1)
Text("Item subtitle")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(1)
}
}
}
.margins(.all, 5)
return cell
}
dataSource.supplementaryViewProvider = { [unowned self] collectionView, elementKind, indexPath in
return collectionView.dequeueConfiguredReusableSupplementary(using: headerRegistration, for: indexPath)
}
}
func applySnapshot(animatingDifferences: Bool = true) {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems(items)
dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
}
}
Upvotes: 0
Views: 30