1

I have a pretty simple UICollectionView requirement. For iPhone 6/6s/7 and 6/6s/7 Plus sizes the two cells must show side by side i.e. two cells per line. And for iPhone 5/5s/SE it should show 1 cell per line. My cell height is fixed pretty much to 194.

Now I have this code in the view controller to achieve this somewhat-

import UIKit

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!
    var screenWidth: CGFloat!


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .blue

        screenWidth = collectionView.frame.width

        // Do any additional setup after loading the view, typically from a nib
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
//        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 2)
        layout.itemSize = CGSize(width: screenWidth / 2, height: 194)
        layout.minimumInteritemSpacing = 0
        collectionView.collectionViewLayout = layout
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColor = UIColor.blue
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath as IndexPath) as UICollectionViewCell
        cell.backgroundColor = UIColor.white
        cell.layer.borderColor = UIColor.black.cgColor
        cell.layer.borderWidth = 0.5
        return cell
    }

}

The resulting output is this-

enter image description here

As you can see, the iPhone Plus size and the 5/5s/SE layouts are fine or I should say that I am fine with those with what I have, but the second i.e. for 6/6s/7 sizes the cells are almost stuck to each other. I know that I have layout.minimumInteritemSpacing = 0 but if I increase this to even by 1 then the cells will be pushed down just like the third image, using UIEdgeInsets are also causing the same issue.

My entire UICollectionView is pinned top 0 , bottom 0 , left 8 and right 8 to the superview. I reviewed a few Q&As in SO which are somewhat related to this and suggests using UICollectionViewDelegateFlowLayout's sizeForItemAt function, but I haven't been able to resolve this using that either.

How do I resolve the spacing issue for 6/6s/7 screen width to have two cells in a line with some spacing? My ultimate goal is to have 2 cells per line on devices 6 and above and 1 cell per line for devices 5s and below (includes SE). Can this be done?

Anjan Biswas
  • 7,746
  • 5
  • 47
  • 77

1 Answers1

2

You need to take into account the collectionViews edge insets and minimumInteritemSpacing before creating a size. You should really implement the UICollectionViewFlowLayoutDelegate methods for laying out the collectionView. Your width should be (screenSize - left inset - right inset - minimumInteritemSpacing) / 2.

EDIT

Why not check what device it is and then return a size based on that?

e.g

if iPhone6 {
    return size / 2
} else {
    return size
}

To check what device it currently is refer to the following answer.

Harry Singh
  • 826
  • 5
  • 11
  • Harry, I did try `sizeForItemAt` and although it resolves the spacing issue it also makes me fix the number of cells per line on any device, which is not quite my requirement. My requirement is to show 2 cells per line for devices iPhone 6 and above and 1 cell per line on devices 5s/5/SE. Not sure if it is even possible. – Anjan Biswas Jul 04 '17 at 02:24
  • Great. I was looking for something like that almost like using media queries in web. But unfortunately now that I am looking at the sheer number of models I don't want the app to break as soon as Apple releases the next one. I used your previously recommended approach using UICollectionViewDelegateFlowLayout and although it will make the number of cells fixed per line I am satisfied for now. Thanks for the help. – Anjan Biswas Jul 04 '17 at 04:02