iosswiftuicollectionviewuikituicollectionviewcompositionallayout

Unwanted space between Collection View cells Compositional Layout


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 wanted result: Wanted Result

The current result: Initial state Initial Scrolled state Unwanted space

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.


Solution

  • 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:

    // MARK: - Group
    
    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(124))
    

    After that, I change the group's width to absolute(widthValue). That fixed the unwanted space.

    // MARK: - Group
    
    let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(686), heightDimension: .absolute(120))
    

    Result: Initial Initial Position

    Scrolled Scrolled Position

    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)