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

后端 未结 11 2097
不知归路
不知归路 2021-02-14 11:25

Description:

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

I usually would try to conver

相关标签:
11条回答
  • 2021-02-14 11:29

    This ended up being the solution I used. Read the code comments for a better understanding. Swift 5

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    
        //Where elements_count is the count of all your items in that
        //Collection view...
        let cellCount = CGFloat(elements_count)
    
        //If the cell count is zero, there is no point in calculating anything.
        if cellCount > 0 {
            let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
            let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing
    
            //20.00 was just extra spacing I wanted to add to my cell.
            let totalCellWidth = cellWidth*cellCount + 20.00 * (cellCount-1)
            let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right
    
            if (totalCellWidth < contentWidth) {
                //If the number of cells that exists take up less room than the
                //collection view width... then there is an actual point to centering them.
    
                //Calculate the right amount of padding to center the cells.
                let padding = (contentWidth - totalCellWidth) / 2.0
                return UIEdgeInsets(top: 0, left: padding, bottom: 0, right: padding)
            } else {
                //Pretty much if the number of cells that exist take up
                //more room than the actual collectionView width, there is no
                // point in trying to center them. So we leave the default behavior.
                return UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)
            }
        }
        return UIEdgeInsets.zero
    }
    
    0 讨论(0)
  • 2021-02-14 11:32

    Here's a recent solution, works for Swift 5.0

    extension YourViewController: UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            insetForSectionAt section: Int) -> UIEdgeInsets {
            let itemWidth = 80
            let spacingWidth = 4
            let numberOfItems = collectionView.numberOfItems(inSection: section)
            let cellSpacingWidth = numberOfItem * spacingWidth
            let totalCellWidth = numberOfItems * itemWidth + cellSpacingWidth
            let inset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth)) / 2
            return UIEdgeInsets(top: 5, left: inset, bottom: 5, right: inset)
        }
    }
    
    0 讨论(0)
  • 2021-02-14 11:33

    Assuming that you are conforming to UICollectionViewDelegateFlowLayout, it should be:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2
        return UIEdgeInsets(top: 0, left: edgeInsets, bottom: 0, right: 0)
    }
    
    0 讨论(0)
  • 2021-02-14 11:36

    The method that you are looking for is present with a different signature in Swift 3. The new signature is this:

    optional public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
    

    P.S: This method is present in UICollectionViewDelegateFlowLayout protocol.
    Hope this would help.

    0 讨论(0)
  • 2021-02-14 11:38

    I think the easiest solution in case your collectionView has one row is to substitute it by a stackView inside a scrollview so you can set the spacing you want between the views. Besides, if you want some padding you will be able apply it.

    0 讨论(0)
  • 2021-02-14 11:39

    Slight adaptation of @rottenoats answer. This is more generic.

    Most importantly remember to make your view controller conform to the UICollectionViewDelegateFlowLayout protocol.

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    
        guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else {
            return .zero
        }
    
        let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
    
        if cellCount > 0 {
            let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing
    
            let totalCellWidth = cellWidth * cellCount
            let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right - flowLayout.headerReferenceSize.width - flowLayout.footerReferenceSize.width
    
            if (totalCellWidth < contentWidth) {
                let padding = (contentWidth - totalCellWidth + flowLayout.minimumInteritemSpacing) / 2.0
                return UIEdgeInsetsMake(0, padding, 0, 0)
            }
        }
    
        return .zero
    }
    
    0 讨论(0)
提交回复
热议问题