I am using Collection View for a scene. I created a custom compositional layout which is like down below. However, while scrolling there is an unwanted space between the second part of the cells. It has occurred in different cell types. I checked the spacing or insets but I couldn’t figure out the reason.
The compositional layout part :
struct UIHelper {
static func createLayouts(section: [SectionType], sectionIndex: Int) -> NSCollectionLayoutSection {
switch section[sectionIndex] {
case .sevenDaysWeather(_):
// MARK: - Item
let itemSize = NSCollectionLayoutSize(widthDimension: .absolute(70), heightDimension: .absolute(124))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// MARK: - Group
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(124))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.interItemSpacing = .fixed(12)
// MARK: - Section
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous
// MARK: - Header
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(24))
let headerKind = UICollectionView.elementKindSectionHeader
let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: headerKind, alignment: .top)
section.boundarySupplementaryItems = [headerElement]
section.contentInsets = NSDirectionalEdgeInsets(top: 12, leading: 16, bottom: 20, trailing: 0)
return section
}
}
The collection view part:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let type = sections[indexPath.section]
switch type {
case .sevenDaysWeather(let viewModels):
guard let sevenDaysCell = collectionView.dequeueReusableCell(withReuseIdentifier: SevenDaysCollectionViewCell.identifer, for: indexPath) as? SevenDaysCollectionViewCell else { return UICollectionViewCell()}
sevenDaysCell.configure(with: viewModels[indexPath.row])
return sevenDaysCell
}
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: HeaderCollectionReusableView.identifier, for: indexPath) as! HeaderCollectionReusableView
header.configure(section: sections, indexPath: indexPath)
return header
}
}
The current result:
Initial state
Scrolled state
Edit: Normally I have two more sections in the collection view. In order to make the example more clear I trim those parts. But the logic was the same with the given example.
3
Answers
After a while, I realized that the problem was related to the width size of the layout group.
In the initial version that I posted, in the compositional layout group properties, I was using fractionalWidth in group size.
Like this:
After that, I change the group's width to absolute(widthValue). That fixed the unwanted space.
Result: Initial
Scrolled
Explanation of absolute and fractional can be found in Apple's documentation
Note: I calculated the total widthValue like this:
(numberOfCells * cell widht) + ((numberOfCells - 1) * interSpacingValue)
I fixed it like this, but I wonder if there are a cleaner way:
My cells are dynamically sized. So it doesn’t work to calculate width beforehand. And .absolute sizing doesn’t work.
Here’s a simpler way of doing it:
Set 1-item-per-group using the count param. Each item is its own group. And have your items & groups size themselves dynamically using .estimated width. Lastly, NSCollectionLayoutGroup must be set to vertical.