0

I am a noob to SWIFT but I am trying to create a CollectionView. When I run the following code on an iPhone 11 simulator the CollectionView gives me three images per row, which is the result that I want. However, when I run the code on any other device I get what seems like a blank cell between the first and third cell on each row. The image below shows the difference between the working version (11 max pro) and the flawed version (SE). I am not sure what I am doing wrong or how to correct it. I am open to any suggestions on how to fix it or a better way to write the code.

var collectionViewFlowLayout: UICollectionViewFlowLayout!
let cellIdentifier = "ItemCollectionViewCell"

override func viewDidLoad() {
    super.viewDidLoad()
    setupCollectionView()
}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
            setupCollectionViewItemSize()
}

private func setupCollectionView(){
    collectionView.delegate = self
    collectionView.dataSource = self
    let nib = UINib(nibName: "ItemCollectionViewCell", bundle: nil)
    collectionView.register(nib, forCellWithReuseIdentifier: cellIdentifier)
}

    private func setupCollectionViewItemSize(){
        if collectionViewFlowLayout == nil {
            let numberOfItemsPerRow: CGFloat = 3
            let lineSpacing: CGFloat = 5
            let interItemSpacing: CGFloat = 5
            let width = (collectionView.frame.width - (numberOfItemsPerRow - 1) * interItemSpacing) / numberOfItemsPerRow
            let height = width

            collectionViewFlowLayout = UICollectionViewFlowLayout()
            collectionViewFlowLayout.itemSize = CGSize(width: width, height: height)
            collectionViewFlowLayout.sectionInset = UIEdgeInsets.zero
            collectionViewFlowLayout.scrollDirection = .vertical
            collectionViewFlowLayout.minimumLineSpacing = lineSpacing
            collectionViewFlowLayout.minimumInteritemSpacing = interItemSpacing
            collectionView.setCollectionViewLayout(collectionViewFlowLayout, animated: true)
        }
    }

example of two views

Part_Time_Nerd
  • 994
  • 7
  • 26
  • 56

1 Answers1

0

I was able to solve it by adding UICollectionViewDelegateFlowLayout to the view controller as well as a function that I found on SO.

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ItemCollectionViewCell
        
        cell.imageView.image = UIImage(named: items[indexPath.item].imageName)
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let item = items[indexPath.item]
        performSegue(withIdentifier: viewImageSegueIdentifier, sender: item)
    }
    
    //****This is the function that I added ****//
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let noOfCellsInRow = 3
        let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
        let totalSpace = flowLayout.sectionInset.left
            + flowLayout.sectionInset.right
            + (flowLayout.minimumInteritemSpacing * CGFloat(noOfCellsInRow - 1))

        let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(noOfCellsInRow))
        return CGSize(width: size, height: size)
    }
}
Part_Time_Nerd
  • 994
  • 7
  • 26
  • 56