collectionview cell interitem space is not fixed

57 views Asked by At

I have a collectionview with dynamic width cells & scroll is vertical. So when first two text are small and third is large, the two cells are leaving more space in between them and third one getting down in second row. I want 1st and 2nd cell to keep inter-item-spacing intact and leave extra space at the end of the row.

enter image description here

the 1st and 2nd also should be just like the 3rd line. leave extra space at the end of the row. is it possible?

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if property.keySizeGuide?.lowercased().contains("size") ?? false {
            return setTextCellSize(path: indexPath)
        }
        if let imgUrl = property.nameValues?[indexPath.row].imgUrl, !imgUrl.isEmpty && checkForImageColorValues().0 {
            return CGSize(width: 96, height: 96)
        }
        if let hexColor = property.nameValues?[indexPath.row].hexColor, !hexColor.isEmpty && checkForImageColorValues().1 {
            return CGSize(width: 48, height: 48)
        }
        return setTextCellSize(path: indexPath)
    }

 private func setTextCellSize(path: IndexPath) -> CGSize {
    let widthLabel = property.nameValues?[path.row].value.width(withConstraintedHeight: 20, font: .systemFont(ofSize: 14, weight: .semibold)) ?? 0
    return CGSize(width: widthLabel+45, height: 48)
}
1

There are 1 answers

0
deniz On

I answered a similar layout question here on Stack Overflow. You are using the legacy FlowLayout. Unfortunately, this is how it works. As Larme mentioned in the comments to your question, you can either create your own layout or switch to the newer CompositionalLayout or find a 3rd party solution. I recommend using this library which is built on top of the Compositional Layout and simplifies the usage of CompositionalLayouts tremendously. If you end up using Composure, your layout code will look like this: (Notice, you don't have to provide exact measurements of your cells which is great in your case as your view needs self-sizing cells)

import UIKit
import Composure

enum LayoutSections: Int, CaseIterable, DefinesCompositionalLayout {
    //list the number of sections in your layout. in this example 
    //there are 2 sections with different layout requirements
    case section1
    case section2
    
    func layoutInfo(using layoutEnvironment: NSCollectionLayoutEnvironment) -> CompositionalLayoutOption {
        switch self {
        case .section1:
            return .fullWidthDynamicHeight(estimatedHeight: 120)
        case .section2:
            return .dynamicWidthFixedHeight(estimatedWidth: 180, fixedHeight: 150)
        }
    }
}

Then in your view controller you create the layout with one line of code:

import UIKit
import Composure

class MyViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.collectionViewLayout = generateCompositionalLayout(with: LayoutSections.allCases)
        //...
    }
    ...
}