Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView 3 column grid, 1px space?? (image included)

I have setup a UICollectionView with a FlowLayout that leaves no space in between cells in either the vertical or horizontal directions.

I have everything working, yet there is an odd 1px space between the 2nd and 3rd column and I have no idea why!? I have verified the 1px gap shows up both in iOS simulator and on a real device. Has anybody experienced this?

My UIViewController is a delegate/datasource of the following:

class MyViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout

I have implemented the necessary functions to remove any spacing (and verified with print statements that they are running), as well as visual confirmation of the cells lining up next to each other:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    return UIEdgeInsetsZero
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

Finally, I have printed out the width of the cell being returned (each color square) to verify it was the (view.frame.width / 3) or (320/3), which is 106.666667

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    var totalHeight: CGFloat = (self.view.frame.width / 3)
    var totalWidth: CGFloat = (self.view.frame.width / 3)

    println(totalWidth) // this prints 106.666666667

    return CGSizeMake(totalWidth, totalHeight)
}

enter image description here

like image 418
Alex Avatar asked Apr 04 '15 00:04

Alex


3 Answers

Better avoid number's double type in similar situations. Use:

return CGSizeMake(ceil(totalWidth), ceil(totalHeight))
like image 103
dimpiax Avatar answered Oct 21 '22 16:10

dimpiax


I was having the same problem, I fixed it with the code below:

 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    let paddingSpace = sectionInsets.left * 4
    let availableWidth = view.frame.width - paddingspace
    let widthPerItem  = availableWidth/3

    return CGSizeMake(width: widthPerItem, height: widthPerItem)
}

and define the variable below in the begin of your class:

fileprivate let sectionInsets = UIEdgeInsets(top: 0.0, left: 0.5, bottom: 0.0, right: 0.0)
like image 26
Tiago Couto Avatar answered Oct 21 '22 14:10

Tiago Couto


For example you have screen width = 320, when you divide it by 3 you have 106.6666. If consider it as Int, we have: 106 * 3 = 318. We need 2 pixel to be added by 1 px to first two cells because 320 - 318 = 2. Try this solution below.

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let columns = 3 
    let width = Int(UIScreen.main.bounds.width)
    let side = width / columns
    let rem = width % columns
    let addOne = indexPath.row % columns < rem
    let ceilWidth = addOne ? side + 1 : side
    return CGSize(width: ceilWidth, height: side)
}
like image 33
Asike Avatar answered Oct 21 '22 14:10

Asike