0

Note, I have scoured the internet and have not found a place to both size and centers cells that works. I tried doing it myself but I keep running to bugs I can't avoid. I am new to Swift. My code:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath:IndexPath) -> CGSize {
        let cellWidth = collectionView.frame.size.width / 7.0
        let cellHeight = collectionView.frame.height - 4.0
        let imageSideLength = cellWidth < cellHeight ? cellWidth : cellHeight
        return CGSize(width: imageSideLength, height: imageSideLength)
    }

    //centers the cells
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        // Make sure that the number of items is worth the computing effort.
        guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout,
            let dataSourceCount = photoCollectionView.dataSource?.collectionView(photoCollectionView, numberOfItemsInSection: section),
            dataSourceCount > 0 else {
                return .zero
        }

        let cellCount = CGFloat(dataSourceCount)
        let itemSpacing = flowLayout.minimumInteritemSpacing
        let cellWidth = flowLayout.itemSize.width + itemSpacing
        let cellHeight = flowLayout.itemSize.height
        var insets = flowLayout.sectionInset

        // Make sure to remove the last item spacing or it will
        // miscalculate the actual total width.
        let totalCellWidth = (cellWidth * cellCount) - itemSpacing
        let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right
        let contentHeight = collectionView.frame.size.height

        // If the number of cells that exist take up less room than the
        // collection view width, then center the content with the appropriate insets.
        // Otherwise return the default layout inset.
        guard totalCellWidth < contentWidth else {
            return insets
        }

        // Calculate the right amount of padding to center the cells.
        let padding = (contentWidth - totalCellWidth) / 2.0
        insets.left = padding
        insets.right = padding
        insets.top = (contentHeight - cellHeight) / 2.0
        //insets.bottom = (contentHeight - cellHeight) / 2.0
        return insets
    }
}

I try to use two separate functions: the first to size the cells and the second to center the cells. (Note I only want new cells to expand horizontally, with a maximum of 6 cells.) However, my calculation of cell height and width in the 2nd function does not agree with how I set it in the first function, setting off a chain of issues. Any insight on how to both size and center the cells such that I can have 1-6 cells horizontally fit on my screen centered would be great.

Alex Kornhauser
  • 444
  • 4
  • 13
  • 34

1 Answers1

1

Your layout calls are conflicting. Try following THIS Tutorial to get the hang of it.

Otherwise a good answer for this is HERE

var flowLayout: UICollectionViewFlowLayout {
    let _flowLayout = UICollectionViewFlowLayout()

    // edit properties here
    _flowLayout.itemSize = CGSize(width: 98, height: 134)
    _flowLayout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 5)
    _flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal
    _flowLayout.minimumInteritemSpacing = 0.0
    // edit properties here

    return _flowLayout
}

Set it with:

self.collectionView.collectionViewLayout = flowLayout // after initializing it another way
// or
UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
Jake
  • 1,335
  • 1
  • 7
  • 19
  • Thank you very much for your response. I'm actually not looking to allow horizontal scrolling. I want all the cells to fit on the same screen, centered. – Alex Kornhauser Mar 01 '18 at 01:57
  • This is more of an example on how to properly use the `flowLayout` you can customize this how you want to – Jake Mar 01 '18 at 01:58
  • Where do I call this? Will calling this set the cell size? – Alex Kornhauser Mar 01 '18 at 02:00
  • You can call it in `viewDidLoad()` and yes you want to replace `width`, `height`, and `minimumInteritemSpacing` with the values you want. – Jake Mar 01 '18 at 02:02
  • So this does the same thing as: `func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath:IndexPath) -> CGSize {` ? – Alex Kornhauser Mar 01 '18 at 02:11
  • essentially. Only with more options. You should do the tutorial I left in the answer. – Jake Mar 01 '18 at 02:14