Set collectionView size. (sizeForItemAtIndexPath function is not working) Swift 3
IosSwiftUicollectionviewTableviewIos 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
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