Set collectionView size. (sizeForItemAtIndexPath function is not working) Swift 3

IosSwiftUicollectionviewTableview

Ios Problem Overview


I have a tableView and in every tableViewCell is a collectionView.

I am trying to change the collectionView size with this code:

 func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    
    if collectionView.tag == 2{
        
        return CGSize(width: 100, height: 100)
        
    }else if collectionView.tag == 4 {
        
        
        return CGSize(width: 222, height: 200)
        
    }else{
        
        
        return CGSize(width: 10, height: 10)
    }
    
}

The problem is that there is no error but cells do not change sizes

If you need to know something more, just write a comment.

Thank you.

Ios Solutions


Solution 1 - Ios

First, don't forget to extends from UICollectionViewDelegateFlowLayout delegate.

For single collectionview display logic :

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = ((collectionView.frame.width - 15) / 2) // 15 because of paddings
    print("cell width : \(width)")
    return CGSize(width: width, height: 200)
}

And important point in storyboard don't forget Estimate Size : None

estimate_size_none

Solution 2 - Ios

The signature for this method has changed in Swift 3 to:

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

Pay attention to the subtle difference: (_ collectionView: ... instead of (collectionView: ....

This is because in Swift 3, you have to explicitly specify the label of the first parameter. You can override this default behaviour by adding the underscore character _.

Also, make sure that your class adopts both UICollectionViewDelegate and UICollectionViewDelegateFlowLayout protocols

class MyViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {

    // your code here

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

Refer to this link to learn more about changes in Swift 3.

Solution 3 - Ios

You need to specify that you implement the protocol UICollectionViewDelegateFlowLayout in your class declaration.

class PhrasesCompactCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout

Solution 4 - Ios

So This is my code right now and it works:

        collectionView.delegate = dataSourceDelegate
        collectionView.dataSource = dataSourceDelegate
        collectionView.tag = row
        collectionView.setContentOffset(collectionView.contentOffset, animated:false)
        collectionView.reloadData()
        collectionView.register(UINib(nibName: "eventsCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "eventsCollectionViewCell")
    

        if row == 2{
            
            
            let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            layout.itemSize = CGSize(width: 120, height: 120)
            layout.scrollDirection = .horizontal
            
            collectionView.collectionViewLayout = layout
       
        }else if row == 4 {
            
            
            let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            layout.itemSize = CGSize(width: 222, height: 200)
            layout.scrollDirection = .horizontal
            
            collectionView.collectionViewLayout = layout
            
        }else{
            
            print("else")
        }

Solution 5 - Ios

Short Version:

Try adding

collectionView.delegate = dataSource

Longer version:

For Me this was a small mistake -

collectionView.dataSource = self

This would call these methods

func numberOfSections(in collectionView: UICollectionView) -> Int
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

However it would NOT call

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

Because this is not part of UICollectionView 's dataSource. It's part of UICollectionView's delegate.

So adding the following solved my issue.

collectionView.delegate = dataSource

Solution 6 - Ios

I've had the same problem! If you make the size half the width (width/2), then it will still appear like the entire width because the padding is being added to the width/2.

Fix: Make sure to set the section insets in Storyboard to 0. Alternatively, adjust the width/2 to a size that INCLUDES the section insets.

It took me a while to fix that one ;-)

Solution 7 - Ios

Don't forget to assign UICollectionViewFlowLayout object to your collectionViewLayout since UICollectionView uses UICollectionViewLayout (not UICollectionViewFlowLayout) by default.

> let flowLayout = UICollectionViewFlowLayout() > > collectionView.collectionViewLayout = flowLayout

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question0ndre_View Question on Stackoverflow
Solution 1 - IosBurak DizlekView Answer on Stackoverflow
Solution 2 - IosPedro ManchenoView Answer on Stackoverflow
Solution 3 - IosVikas KrishnanView Answer on Stackoverflow
Solution 4 - Ios0ndre_View Answer on Stackoverflow
Solution 5 - IosBLCView Answer on Stackoverflow
Solution 6 - Iost.berlinView Answer on Stackoverflow
Solution 7 - IosValeriaView Answer on Stackoverflow