Aligning collection view cells to fit exactly 3 pe

2019-03-28 18:23发布

问题:

I am trying to make a collection view of images, so that there are 3 per row, with no spacing in between.

My collection view data sources are:

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

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

and this is how it's set up in my storyboard (imageView width is 125, a third of the 375 screen width):

However when I run the app and add some photos, it looks like this:

How can I fix this so that I see 3 images per row? Thanks for any help!

回答1:

You have to implement the

UICollectionViewDelegateFlowLayout

for the spacing stuff.

Set the size of the collectionViewCells like this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let yourWidth = collectionView.bounds.width/3.0
    let yourHeight = yourWidth

    return CGSize(width: yourWidth, height: yourHeight)
}

You can also add these functions to get your spacing of the collectionViewCells correct:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets.zero
}

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
}


回答2:

1- You have to conform to UICollectionViewDelegateFlowLayout

2- You should implement collectionView(_:layout:sizeForItemAt:) method, as follows:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let screenWidth = UIScreen.main.bounds.width
    let scaleFactor = (screenWidth / 3) - 6

    return CGSize(width: scaleFactor, height: scaleFactor)
}

Assuming that the minimum spaces are 8 -for example-,

the output should be three items for each row, square sized.

Remark: If you want to set the spaces between the cells to be zero, then scaleFactor should be:

let scaleFactor = (screenWidth / 3)

Hope this helped.



回答3:

Swift - Version 4.2

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) 
}


回答4:

You have to implement the

UICollectionViewDelegateFlowLayout for the spacing stuff.

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UpperCollectionViewCell", for: indexPath) as! UpperCollectionViewCell
    return cell
}

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

    return CGSize(width: (self.collectionView.frame.width/3.0) - 5 , height: (self.collectionView.frame.height/4.0))
}

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