amodkanthe
amodkanthe

Reputation: 4530

cellForItemAt not called if numberOfItemsInSection is 1 UICollectionView

Following is my code which is working fine if numberOfItemsInSection is greater than 1 but if numberOfItemsInSection is equal to 1 it should display single cell but it is not happening, for numberOfItemsInSection equals 1 noting is displayed and cellForItemAt is not called

Also initial numberOfItemsInSection is Zero after making api call and receiving data it becomes one and I call following code as well

tabsCollectionView.reloadData()

Other code

    tabsCollectionView.delegate = self
    tabsCollectionView.dataSource = self




func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return menuResult?.foodMenuItems?.count ?? 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = tabsCollectionView.dequeueReusableCell(withReuseIdentifier: "foodTabsCollectionViewCellID", for: indexPath) as! FoodTabsCollectionViewCell
    cell.foodMenuItem = menuResult?.foodMenuItems?[indexPath.row]
    cell.setUI()
    return cell
}


func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1

}

following code related sizing in side viewDidLoad()

 if let flowLayout = tabsCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.estimatedItemSize = CGSize(width: 200, height: 70)
        flowLayout.itemSize = UICollectionViewFlowLayout.automaticSize
        tabsCollectionView.collectionViewLayout = flowLayout
    }

sizeForItemAt method

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    var height = collectionView.frame.height
    var width  = collectionView.frame.width
    if let flowLayout  = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        width = flowLayout.estimatedItemSize.width
        height = flowLayout.estimatedItemSize.height
    }

    return CGSize(width: width, height: height)
}

Following is code inside FoodTabsCollectionViewCell

 override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    setNeedsLayout()
    layoutIfNeeded()
    let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
    var frame = layoutAttributes.frame
    frame.size.width = ceil(size.width)
    frame.size.height = ceil(size.height)
    layoutAttributes.frame = frame
    layoutIfNeeded()
    return layoutAttributes
}

Upvotes: 2

Views: 1208

Answers (2)

Negar
Negar

Reputation: 121

The problem will happen when the collectionView scroll direction is horizontal and the height of collectionView is less than 50. I had the same problem and I increased the collectionView height to 50 then the problem solved.

Upvotes: 1

christostsang
christostsang

Reputation: 1841

I had the same problem when I tried to set a flexible width to a cell containing a UILabel with variable width (actually the size was related to the width of the text of the UILabel)

So initially I was using this approach (THIS was causing the problems):

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize <--- THIS
layout.itemSize.height = 70 <-- THIS

Then I removed the automaticSize (and itemSize.height) as below:

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal

And it worked.

To make sure that I had flexible cell width I used this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    
    let dummyCell = MyCell(frame: .init(x: 0, y: 0, width: frame.width, height: 40))
    
    
    dummyCell.name = users[indexPath.item].name
    
    // 3. Force the view to update its layout
    dummyCell.layoutIfNeeded()
    
    // 4. Calculate the estimated size
    let estimatedSize = dummyCell.systemLayoutSizeFitting(.init(width: frame.width, height: 40))
    
    return CGSize(width: estimatedSize.width, height: 40)
}

Upvotes: 0

Related Questions