Pritesh
Pritesh

Reputation: 139

UICollectionView cells lining vertically instead of grid

I am trying to create UICollectionView programatically, and my cells are getting stacked vertically instead of a grid form. enter image description here

My code is:

    let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let screenSize: CGRect = UIScreen.main.bounds
    let screenWidth = screenSize.width

    let width = (screenWidth - 4)/3
    layout.itemSize = CGSize(width: width, height: width+20)
    layout.sectionInset = UIEdgeInsets(top:0,left:0,bottom:0,right:0)
    collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    collectionView?.dataSource = self
    collectionView?.delegate=self
    collectionView?.collectionViewLayout = layout
    collectionView?.register(NearbyCollectionViewCell.self, forCellWithReuseIdentifier: "cellId")

    self.view.addSubview(collectionView!)

Upvotes: 2

Views: 242

Answers (2)

iSlam AbdelAziz
iSlam AbdelAziz

Reputation: 3

You Can use UICollectionViewDelegateFlowLayout as Follows:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let itemWidth: CGFloat = (screenWidth - 4)/3
    let itemHeight: CGFloat = itemWidth + 20

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

Upvotes: 0

Ratnesh Jain
Ratnesh Jain

Reputation: 681

You should always consider collectionView's frame for item size calculation.

In your question you are using UIScreen's width which might get you to wrong calculations because of collectionView's inset properties.

let screenSize: CGRect = UIScreen.main.bounds

let screenWidth = screenSize.width

For correct size calculation lets define the number of items in single row.

let maximumItemInRow = 3 (You can play with this as per your requirement)

Now implementing the UICollectionViewDelegateFlowLayout's sizeForItem method.

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    // Getting collectionView's size
    var width = collectionView.frame.width
    var height = collectionView.frame.height
    
    // Respecting collectionView's ContentInsets properties
    width -= (collectionView.contentInset.left + collectionView.contentInset.right)
    height -= (collectionView.contentInset.top + collectionView.contentInset.bottom)
    
    if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
        
        // Respecting flowLayout's sectionInset properties
        width -= (flowLayout.sectionInset.left + flowLayout.sectionInset.right)
        height -= (flowLayout.sectionInset.top + flowLayout.sectionInset.bottom)
        
        // In Vertically scrolling Flow layout
        width -= flowLayout.minimumInteritemSpacing
        height -= flowLayout.minimumLineSpacing
    }
    
    // After considering contentInset and sectionInsets 
    // we can calculate the width according to 
    // number of items in single row. 
    return CGSize(width: width / maximumItemInRow, height: height)
}

Upvotes: 3

Related Questions