How can I center rows in UICollectionView?

前端 未结 9 1615
囚心锁ツ
囚心锁ツ 2021-02-02 06:24

I have a UICollectionView with random cells. Is there any method that allows me to center rows?

This is how it looks by default:

[ x x x x         


        
9条回答
  •  春和景丽
    2021-02-02 07:05

    This can be achieved with a (relatively) simple custom layout, subclassed from UICollectionViewFlowLayout. Here's an example in Swift:

    /**
     * A simple `UICollectionViewFlowLayout` subclass that would make sure the items are center-aligned in the collection view, when scrolling vertically.
     */
    class UICollectionViewFlowCenterLayout: UICollectionViewFlowLayout {
    
        override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let suggestedAttributes = super.layoutAttributesForElementsInRect(rect) else { return nil }
    
            guard scrollDirection == .Vertical else { return suggestedAttributes }
    
            var newAttributes: [UICollectionViewLayoutAttributes] = []
    
            /// We will collect items for each row in this array
            var currentRowAttributes: [UICollectionViewLayoutAttributes] = []
            /// We will use this variable to detect new rows when iterating over items
            var yOffset:CGFloat = sectionInset.top
            for attributes in suggestedAttributes {
                /// If we happen to run into a new row...
                if attributes.frame.origin.y != yOffset {
                    /*
                     * Update layout of all items in the previous row and add them to the resulting array
                     */
                    centerSingleRowWithItemsAttributes(¤tRowAttributes, rect: rect)
                    newAttributes += currentRowAttributes
                    /*
                     * Reset the accumulated values for the new row
                     */
                    currentRowAttributes = []
                    yOffset = attributes.frame.origin.y
                }
                currentRowAttributes += [attributes]
            }
            /*
             * Update the layout of the last row.
             */
            centerSingleRowWithItemsAttributes(¤tRowAttributes, rect: rect)
            newAttributes += currentRowAttributes
    
            return newAttributes
        }
    
        /**
         Updates the attributes for items, so that they are center-aligned in the given rect.
    
         - parameter attributes: Attributes of the items
         - parameter rect:       Bounding rect
         */
        private func centerSingleRowWithItemsAttributes(inout attributes: [UICollectionViewLayoutAttributes], rect: CGRect) {
            guard let item = attributes.last else { return }
    
            let itemsCount = CGFloat(attributes.count)
            let sideInsets = rect.width - (item.frame.width * itemsCount) - (minimumInteritemSpacing * (itemsCount - 1))
            var leftOffset = sideInsets / 2
    
            for attribute in attributes {
                attribute.frame.origin.x = leftOffset
                leftOffset += attribute.frame.width + minimumInteritemSpacing
            }
        }
    }
    

提交回复
热议问题