|
//
// CenterAlineCollectionViewLayout.swift
// savePassword
//
// Created by FFIB on 16/3/21.
// Copyright © 2016年 FFIB. All rights reserved.
//
import UIKit
protocol WaterFlowCollectionViewLayoutDelegate: UICollectionViewDelegateFlowLayout {
func collectionLayoutHasPrepared(_ collectionView: UICollectionView )
func collectionViewLayout(collectionView: UICollectionView, sizeOfHeaderViewAtIndex indexpath: IndexPath) -> CGSize
}
class WaterFlowCollectionViewLayout: UICollectionViewFlowLayout {
var paddingX: CGFloat = 6
var paddingY: CGFloat = 6
var layoutCacheLeft = [UICollectionViewLayoutAttributes]()
var layoutCacheRight = [UICollectionViewLayoutAttributes]()
var layoutCache = [UICollectionViewLayoutAttributes]()
var headerHeight: CGFloat = 0
override func prepare() {
layoutCacheLeft.removeAll()
layoutCacheRight.removeAll()
guard let collectionView = collectionView else {
return
}
headerHeight = (collectionView.delegate as? UICollectionViewDelegateFlowLayout)?.collectionView!(self.collectionView!, layout: self, referenceSizeForHeaderInSection: 0).height ?? 0
let lastRowHeight: CGFloat = headerHeight + 6
for section in 0..<collectionView.numberOfSections {
autoreleasepool(invoking: { () in
let itemsCount = collectionView.numberOfItems(inSection: section)
for row in 0..<itemsCount {
autoreleasepool(invoking: { () in
let indexPath = IndexPath(item: row, section: section)
var itemSize = CGSize(width: 10, height: 10)
if let layoutDelegate = collectionView.delegate as? UICollectionViewDelegateFlowLayout, let size = layoutDelegate.collectionView?(collectionView, layout: self, sizeForItemAt: indexPath) {
itemSize = size
}
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
if layoutCacheLeft.count == 0 {
attributes.frame = CGRect(x: 0, y: lastRowHeight, width: itemSize.width, height: itemSize.height)
layoutCacheLeft.append(attributes)
} else if layoutCacheRight.count == 0 {
attributes.frame = CGRect(x: layoutCacheLeft.last!.frame.maxX + paddingX, y: lastRowHeight, width: itemSize.width, height: itemSize.height)
layoutCacheRight.append(attributes)
} else {
if Int((layoutCacheRight.last?.frame.maxY)!) >= Int((layoutCacheLeft.last?.frame.maxY)!) {
attributes.frame = CGRect(x: 0, y: layoutCacheLeft.last!.frame.maxY + paddingY, width: itemSize.width, height: itemSize.height)
layoutCacheLeft.append(attributes)
} else {
attributes.frame = CGRect(x: layoutCacheLeft.last!.frame.maxX + paddingX, y: layoutCacheRight.last!.frame.maxY + paddingY, width: itemSize.width, height: itemSize.height)
layoutCacheRight.append(attributes)
}
}
})
}
})
}
(collectionView.delegate as? WaterFlowCollectionViewLayoutDelegate)?.collectionLayoutHasPrepared(self.collectionView!)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var result = [UICollectionViewLayoutAttributes]()
let layoutCache = layoutCacheLeft + layoutCacheRight
result = layoutCache.filter({ (attr) -> Bool in
return attr.frame.intersects(rect)
})
if headerHeight != 0 {
let size = CGSize(width: kScreenWidth, height: headerHeight)
let headerAttributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, with: IndexPath(item: 0, section: 0))
headerAttributes.frame = CGRect(x: 0, y: 0, width: (size.width), height: (size.height))
headerAttributes.frame.intersects(rect)
result.append(headerAttributes)
}
return result
}
override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return nil
}
override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView, let lastLeft = layoutCacheLeft.last else {
return CGSize.zero
}
var height: CGFloat = 0
if let lastRight = layoutCacheRight.last {
height = max(lastLeft.frame.maxY, lastRight.frame.maxY)
} else {
height = lastLeft.frame.maxY
}
return CGSize(width: collectionView.frame.size.width, height: height)
}
func collectionViewVisiableMinSize() -> CGSize {
guard let collectionView = collectionView, let lastLeft = layoutCacheLeft.last else {
return CGSize.zero
}
var height: CGFloat = 0
if let lastRight = layoutCacheRight.last {
height = min(lastLeft.frame.maxY, lastRight.frame.maxY)
} else {
height = lastLeft.frame.maxY
}
return CGSize(width: collectionView.frame.size.width, height: height)
}
}
|