UICollectionView反向布局

时间:2016-09-26 13:27:08

标签: ios uicollectionview

我遇到了问题,我想让CollectionView像'聊天'一样。比我应该反转SELECT t1.category, t1.begintime FROM myTable t1 -- current INNER JOIN myTable t2 ON 1=1 -- prev AND t2.begintime < t1.begintime INNER JOIN myTable t3 ON 1=1 -- next AND t3.begintime > t1.begintime LEFT JOIN myTable t4 ON 1=1 -- between current and prev AND t4.begintime < t1.begintime AND t4.begintime > t2.begintime LEFT JOIN myTable t5 ON 1=1 -- between current and next AND t5.begintime > t1.begintime AND t5.begintime < t3.begintime WHERE 1=1 AND t2.category = 'cat1' -- prev cat AND t3.category = 'cat1' -- next cat AND t4.begintime IS NULL -- nothing between current and prev AND t5.begintime IS NULL -- nothing between current and next ; 的布局。我可以配置contentOffset =(0; 0)位于UICollectionView底部的布局(重要我不能UICollectionView CollectionView)? 喜欢

transform

此外,我尝试旋转-> constenOffset = (0; 1000) (for example) | ... | | 2 | | 1 | | 0 | -> constentOffset = (0; 0) ,但在这种情况下UITableView动画不满足我。

1 个答案:

答案 0 :(得分:1)

UICollectionView具有反向的流布局。

import Foundation
import UIKit

class InvertedFlowLayout: UICollectionViewFlowLayout {

    override func prepare() {
        super.prepare()
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard super.layoutAttributesForElements(in: rect) != nil else { return nil }
        var attributesArrayNew = [UICollectionViewLayoutAttributes]()

        if let collectionView = self.collectionView {
            for section in 0 ..< collectionView.numberOfSections {
                for item in 0 ..< collectionView.numberOfItems(inSection: section) {
                    let indexPathCurrent = IndexPath(item: item, section: section)
                    if let attributeCell = layoutAttributesForItem(at: indexPathCurrent) {
                        if attributeCell.frame.intersects(rect) {
                            attributesArrayNew.append(attributeCell)
                        }
                    }
                }
            }

            for section in 0 ..< collectionView.numberOfSections {
                let indexPathCurrent = IndexPath(item: 0, section: section)
                if let attributeKind = layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: indexPathCurrent) {
                    attributesArrayNew.append(attributeKind)
                }
            }
        }

        return attributesArrayNew
    }

    override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attributeKind = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, with: indexPath)

        if let collectionView = self.collectionView {
            var fullHeight: CGFloat = 0.0

            for section in 0 ..< indexPath.section + 1 {
                for item in 0 ..< collectionView.numberOfItems(inSection: section) {
                    let indexPathCurrent = IndexPath(item: item, section: section)
                    fullHeight += cellHeight(indexPathCurrent) + minimumLineSpacing
                }
            }

            attributeKind.frame = CGRect(x: 0, y: collectionViewContentSize.height - fullHeight - CGFloat(indexPath.section + 1) * headerHeight(indexPath.section) - sectionInset.bottom + minimumLineSpacing/2, width: collectionViewContentSize.width, height: headerHeight(indexPath.section))
        }

        return attributeKind
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attributeCell = UICollectionViewLayoutAttributes(forCellWith: indexPath)

        if let collectionView = self.collectionView {
            var fullHeight: CGFloat = 0.0

            for section in 0 ..< indexPath.section + 1 {
                for item in 0 ..< collectionView.numberOfItems(inSection: section) {
                    let indexPathCurrent = IndexPath(item: item, section: section)
                    fullHeight += cellHeight(indexPathCurrent) + minimumLineSpacing

                    if section == indexPath.section && item == indexPath.item {
                        break
                    }
                }
            }

            attributeCell.frame = CGRect(x: 0, y: collectionViewContentSize.height - fullHeight + minimumLineSpacing - CGFloat(indexPath.section) * headerHeight(indexPath.section) - sectionInset.bottom, width: collectionViewContentSize.width, height: cellHeight(indexPath) )
        }

        return attributeCell
    }

    override var collectionViewContentSize: CGSize {
        get {
            var height: CGFloat = 0.0
            var bounds = CGRect.zero

            if let collectionView = self.collectionView {
                for section in 0 ..< collectionView.numberOfSections {
                    for item in 0 ..< collectionView.numberOfItems(inSection: section) {
                        let indexPathCurrent = IndexPath(item: item, section: section)
                        height += cellHeight(indexPathCurrent) + minimumLineSpacing
                    }
                }

                height += sectionInset.bottom + CGFloat(collectionView.numberOfSections) * headerHeight(0)
                bounds = collectionView.bounds
            }

            return CGSize(width: bounds.width, height: max(height, bounds.height))
        }
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        if let oldBounds = self.collectionView?.bounds,
            oldBounds.width != newBounds.width || oldBounds.height != newBounds.height {
            return true
        }

        return false
    }

    func cellHeight(_ indexPath: IndexPath) -> CGFloat {
        if let collectionView = self.collectionView, let delegateFlowLayout = collectionView.delegate as? UICollectionViewDelegateFlowLayout {
            let size = delegateFlowLayout.collectionView!(collectionView, layout: self, sizeForItemAt: indexPath)
            return size.height
        }

        return 0
    }

    func headerHeight(_ section: Int) -> CGFloat {
        if let collectionView = self.collectionView, let delegateFlowLayout = collectionView.delegate as? UICollectionViewDelegateFlowLayout {
            let size = delegateFlowLayout.collectionView!(collectionView, layout: self, referenceSizeForHeaderInSection: section)
            return size.height
        }

        return 0
    }
}