Centering UICollectionView cells in a container

Hey. I need collection cell oriented help via UICollectionViewFlowLayout. My ultimate goal is for the first cell to be in the middle and each cell to snap in the middle. Thank!

Here's what it looks like now: enter image description here

and what I want it to look like this: enter image description here

I found this "solution" on SO, but it does not seem to work properly.

class CenterAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

    let attributes = super.layoutAttributesForElementsInRect(rect)

    // Constants
    let leftPadding: CGFloat = 8
    let interItemSpacing: CGFloat = 5

    // Tracking values
    var leftMargin: CGFloat = leftPadding // Modified to determine origin.x for each item
    var maxY: CGFloat = -1.0 // Modified to determine origin.y for each item
    var rowSizes: [[CGFloat]] = [] // Tracks the starting and ending x-values for the first and last item in the row
    var currentRow: Int = 0 // Tracks the current row
    attributes?.forEach { layoutAttribute in

        // Each layoutAttribute represents its own item
        if layoutAttribute.frame.origin.y >= maxY {

            // This layoutAttribute represents the left-most item in the row
            leftMargin = leftPadding

            // Register its origin.x in rowSizes for use later
            if rowSizes.count == 0 {
                // Add to first row
                rowSizes = [[leftMargin, 0]]
            } else {
                // Append a new row
                rowSizes.append([leftMargin, 0])
                currentRow += 1
            }
        }

        layoutAttribute.frame.origin.x = leftMargin

        leftMargin += layoutAttribute.frame.width + interItemSpacing
        maxY = max(layoutAttribute.frame.maxY, maxY)

        // Add right-most x value for last item in the row
        rowSizes[currentRow][1] = leftMargin - interItemSpacing
    }

    // At this point, all cells are left aligned
    // Reset tracking values and add extra left padding to center align entire row
    leftMargin = leftPadding
    maxY = -1.0
    currentRow = 0
    attributes?.forEach { layoutAttribute in

        // Each layoutAttribute is its own item
        if layoutAttribute.frame.origin.y >= maxY {

            // This layoutAttribute represents the left-most item in the row
            leftMargin = leftPadding

            // Need to bump it up by an appended margin
            let rowWidth = rowSizes[currentRow][1] - rowSizes[currentRow][0] // last.x - first.x
            let appendedMargin = (collectionView!.frame.width - leftPadding  - rowWidth - leftPadding) / 2
            leftMargin += appendedMargin

            currentRow += 1
        }

        layoutAttribute.frame.origin.x = leftMargin

        leftMargin += layoutAttribute.frame.width + interItemSpacing
        maxY = max(layoutAttribute.frame.maxY, maxY)
    }

    return attributes
}
+4
source share
2 answers

Make sure your view controller is a collection view delegate and implements the following method from UICollectionViewDelegateFlowLayout:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    let sideInset = (collectionView.frame.size.width - myCollectionViewCellSize.width) / 2
    return UIEdgeInsets(top: 0, left: sideInset, bottom: 0, right: sideInset)
}
+2
source

UICollectionViewDelegateFlowLayout, collectionView: collectionViewLayout: sizeForItemAtIndexPath.

, (, , , 10.0), :

let width = collectionView.frame.size.width - (margin * 2)

CGSize .

(/, iPads)? willTransitionToTraitCollection viewWillTransitionToSize, , .

0

Source: https://habr.com/ru/post/1648187/


All Articles