UICollection View Flow Layout Vertical Align

后端 未结 10 2141
無奈伤痛
無奈伤痛 2021-02-03 21:45

By default, when you are using the flow layout in a collection view, cells are centered vertically. Is there a way to change this alignment ?

10条回答
  •  既然无缘
    2021-02-03 22:07

    @DongXu: Your solution worked for me too. Here is the SWIFT version if it:

    class TopAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout
    {
        override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]?
        {
            if let attrs = super.layoutAttributesForElementsInRect(rect)
            {
                var baseline: CGFloat = -2
                var sameLineElements = [UICollectionViewLayoutAttributes]()
                for element in attrs
                {
                    if element.representedElementCategory == .Cell
                    {
                        let frame = element.frame
                        let centerY = CGRectGetMidY(frame)
                        if abs(centerY - baseline) > 1
                        {
                            baseline = centerY
                            TopAlignedCollectionViewFlowLayout.alignToTopForSameLineElements(sameLineElements)
                            sameLineElements.removeAll()
                        }
                        sameLineElements.append(element)
                    }
                }
                TopAlignedCollectionViewFlowLayout.alignToTopForSameLineElements(sameLineElements) // align one more time for the last line
                return attrs
            }
            return nil
        }
    
        private class func alignToTopForSameLineElements(sameLineElements: [UICollectionViewLayoutAttributes])
        {
            if sameLineElements.count < 1
            {
                return
            }
            let sorted = sameLineElements.sort { (obj1: UICollectionViewLayoutAttributes, obj2: UICollectionViewLayoutAttributes) -> Bool in
    
                let height1 = obj1.frame.size.height
                let height2 = obj2.frame.size.height
                let delta = height1 - height2
                return delta <= 0
            }
            if let tallest = sorted.last
            {
                for obj in sameLineElements
                {
                    obj.frame = CGRectOffset(obj.frame, 0, tallest.frame.origin.y - obj.frame.origin.y)
                }
            }
        }
    }
    

提交回复
热议问题