0

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

RanLearns
  • 3,731
  • 3
  • 39
  • 69

3 Answers3

1

Have you set Estimate Size is none?

layout:sizeForItemAt: would not call if Estimate Size is Automatic enter image description here

Tam-Thanh Le
  • 333
  • 1
  • 10
  • layout:sizeForItemAt: seems to be specific to UICollectionViewFlowLayout, which I am not using here. I am now seeing that by setting an estimated instead of an actual width, the item adjusts to fit the width of the content within, which is helpful – RanLearns Jun 06 '20 at 04:34
0

You need to conform your view controller to UICollectionViewDelegateFlowLayout and UICollectionViewDelegate both in order to make this method work :

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { }

You are using UICollectionViewCompositionalLayout so you don't need sizeForItemAt:

Please have a look to these tutorials:

Amit
  • 4,157
  • 4
  • 25
  • 40
  • I do conform to both, but myCollectionView uses a custom UICollectionViewLayout and does not use UICollectionViewFlowLayout – RanLearns Jun 06 '20 at 04:31
0

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!

RanLearns
  • 3,731
  • 3
  • 39
  • 69