UICollection View Flow Layout Vertical Align

后端 未结 10 2143
無奈伤痛
無奈伤痛 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

    Swift 3 Version in case someone just wants to Copy & Paste:

    class TopAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            if let attrs = super.layoutAttributesForElements(in: rect) {
                var baseline: CGFloat = -2
                var sameLineElements = [UICollectionViewLayoutAttributes]()
                for element in attrs {
                    if element.representedElementCategory == .cell {
                        let frame = element.frame
                        let centerY = frame.midY
                        if abs(centerY - baseline) > 1 {
                            baseline = centerY
                            alignToTopForSameLineElements(sameLineElements: sameLineElements)
                            sameLineElements.removeAll()
                        }
                        sameLineElements.append(element)
                    }
                }
                alignToTopForSameLineElements(sameLineElements: sameLineElements) // align one more time for the last line
                return attrs
            }
            return nil
        }
    
        private func alignToTopForSameLineElements(sameLineElements: [UICollectionViewLayoutAttributes]) {
            if sameLineElements.count < 1 { return }
            let sorted = sameLineElements.sorted { (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 = obj.frame.offsetBy(dx: 0, dy: tallest.frame.origin.y - obj.frame.origin.y)
                }
            }
        }
    }
    

提交回复
热议问题