Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to center align the cells of a UICollectionView in Swift3.0?

Description:

Answer for Objective-C and Swift2.0: How to center align the cells of a UICollectionView?

I usually would try to convert the Swift2.0 answer to the Swift3.0 solution, however the method:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2
        return UIEdgeInsetsMake(0, edgeInsets, 0, 0);
    }

doesn't seem to exist in Swift3.0,and the only other method I found that seems useful is:

func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout {
        <#code#>
}

but I am unsure how to implement it correctly.

Question:

How to center align the cells of a UICollectionView in Swift3.0?

(A simple and general solution for iOS and tvOS would be perfect)

like image 480
kemicofa ghost Avatar asked Nov 14 '16 09:11

kemicofa ghost


1 Answers

This code should center horizontally any type of collection view even with extra items in Swift 4.0:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    let cellWidth: CGFloat = flowLayout.itemSize.width
    let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
    let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
    var collectionWidth = collectionView.frame.size.width
    if #available(iOS 11.0, *) {
        collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
    }
    let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
    if totalWidth <= collectionWidth {
        let edgeInset = (collectionWidth - totalWidth) / 2
        return UIEdgeInsetsMake(flowLayout.sectionInset.top, edgeInset, flowLayout.sectionInset.bottom, edgeInset)
    } else {
        return flowLayout.sectionInset
    }
}

Don't forget if you are not subclassing UICollectionViewController, make sure your class conforms to UICollectionViewDelegateFlowLayout protocol

like image 184
Saeed Ir Avatar answered Oct 23 '22 03:10

Saeed Ir