UICollectionViewCell width is bigger than what I set in sizeForItemAt

2.6k Views Asked by At

Width/height of my UICollectionView matches all available space.

I want to display two cells in one row (two columns)

So width of one cell should take half width of UICollectionView (collectionView.frame.width / 2)

So I programmatically change width of cell in function of UICollectionViewDelegateFlowLayout:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.width / 2.0, height: 150)
}

But visually width of cell is much bigger than collectionView.frame.width / 2.0 (tested on iPhone SE simulator)

So it takes more than half-width space of screen

Here I printed info about sizes:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
    print("didSelectItemAt \(cell.frame.width), table width: \(collectionView.frame.width), item calc width: \(collectionView.frame.width / 2)")
}

didSelectItemAt cell width 187.5, table width: 375.0, half-width: 187.5

enter image description here

Why does it happen?

There is also an issue with margins but first I have to solve this one

Update

Though it works fine with iPhone 6s Simulator (I edited image to place two items in the first row to check if they fit):

enter image description here

So what is wrong with iPhone SE?

I don't want to find out that there can be the same issue with other iPhones or iPads too

4

There are 4 best solutions below

4
E.Coms On BEST ANSWER

375.0 is the size of iPhone 6s and X, not iPhone SE which is 320.0

The reason is there is a width constraint of collectionView which was set at iPhone 6s mode but later when switching to the SE simulator, this constraint was not updated.

0
Dhaval Bhimani On

I think there is problem of cell spacing. it seems there is default cell spacing exists in your implementation. you should try below code to adjust two cell in one raw of collectionview:

extension ViewController : UICollectionViewDelegateFlowLayout{

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let collectionViewWidth = collectionView.bounds.width
        return CGSize(width: collectionViewWidth/2, height: 150)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
}

moreover, you should check constraint of your UICollectionView if it is as per your requirement Or not.

0
Faysal Ahmed On

Try to use the wide from the view, not the collectionView.

Try this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: (view.frame.width / 2.0) - 5, height: 150) // provide little bit space between cells
}

Hope this will help.

0
Vinodsagar On

The best solution is, to reload your collection view in main thread with a bit delay.

   DispatchQueue.main.asyncAfter(deadline: .now() + 0.10) {
       self.myCollectionView.reloadData()
   }