Search code examples
iosswiftuicollectionviewuicollectionviewcelluicollectionviewlayout

Building UICollectionViewLayout - customize size of a single item


Below is code that works in order to have one sectionIndex of a UICollectionViewLayout with a different width/height for each item in that section compared to other sections. My question is how to further change the width of the first item within this section:

myCollectionView = UICollectionView(frame: myFrame, collectionViewLayout: generateLayout())

.

func generateLayout() -> UICollectionViewLayout {

    let layout = UICollectionViewCompositionalLayout { (sectionIndex: Int,
         layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

     return self.generateStoryLayout(forSection: sectionIndex)
    }
    return layout
}

.

func generateStoryLayout(forSection: Int) -> NSCollectionLayoutSection {
    let itemSize = NSCollectionLayoutSize(
        widthDimension: .fractionalWidth(1.0),
        heightDimension: .fractionalWidth(1.0))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)

    print("generate story layout for this section")

    var groupSize = NSCollectionLayoutSize(
        widthDimension: .absolute(180),
        heightDimension: .absolute(216))

    //taller row in section 1
    if forSection == 1 {
        groupSize = NSCollectionLayoutSize(
             widthDimension: .absolute(250),
             heightDimension: .absolute(300))
    }

    let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1)

    let section = NSCollectionLayoutSection(group: group)
    section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary   //.groupPaging

    return section
}

Thanks so much for any help!

I am separately using a different UICollectionView which uses a UICollectionViewFlowLayout for its layout and the function layout:sizeForItemAt: is called for each item in that UICollectionView and I can determine their sizes there.

The custom myCollectionView doesn't call to this layout:sizeForItemAt:

The ViewController does conform to UICollectionViewDelegate


Solution

  • I received a suggestion here and I saw it repeatedly on other similar threads that "estimate size" needs to be turned off to get layout:sizeForItemAt: to work - but layout:sizeForItemAt: is specific to UICollectionViewFlowLayout, and isn't called by a custom UICollectionViewLayout

    The solution here was actually to use estimated sizes. When telling the collection view cells to estimate the size, you're telling them to use the size of the content to determine the size of the cell.

    My goal was to increase the width of the first cell in a certain section because the image in that cell was wider than the rest. By using a .estimated widthDimension the first cell automatically sized itself larger because of the wider image.

    Thank you UICollectionView!