Anjan Biswas
Anjan Biswas

Reputation: 7932

Dynamically sizing width of UICollectionView cell width for various iPhone screen sizes

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?

Upvotes: 1

Views: 958

Answers (1)

Harry Singh
Harry Singh

Reputation: 816

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.

Upvotes: 2

Related Questions