Нет описания

WaterFlowCollectionViewLayout.swift 5.4KB

    // // 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) } }