// // TableFlowLayout.swift // VDS // // Created by Nadigadda, Sumanth on 02/05/24. // import UIKit import VDSTokens protocol TableCollectionViewLayoutDataDelegate: AnyObject { func collectionView(_ collectionView: UICollectionView, dataForItemAt indexPath: IndexPath) -> TableItemModel } class MatrixFlowLayout : UICollectionViewLayout { weak var delegate: TableCollectionViewLayoutDataDelegate? var layoutPadding: Table.Padding = .standard var itemCache: [UICollectionViewLayoutAttributes] = [] var layoutHeight: CGFloat = 0.0 override func prepare() { super.prepare() itemCache.removeAll() layoutHeight = 0.0 guard let collectionView, let delegate else { return } let sections = collectionView.numberOfSections var yPos: CGFloat = 0.0 for currentSection in 0.. $1.frame.size.height }).first?.frame.size.height ?? 0.0 itemCache.filter({$0.indexPath.section == currentSection}).forEach { attributes in attributes.frame.size.height = highestHeightForSection } yPos += highestHeightForSection } layoutHeight = yPos } private func estimateHeightFor(item: TableItemModel, with width: CGFloat) -> CGFloat { let itemWidth = width - layoutPadding.horizontalValue() - VDSLayout.space1X let height = item.component.estimatedHeight(for: itemWidth) ?? 0 return height + (2 * layoutPadding.verticalValue()) } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var visibleLayoutAttributes: [UICollectionViewLayoutAttributes] = [] for attributes in itemCache { if attributes.frame.intersects(rect) { visibleLayoutAttributes.append(attributes) } } return visibleLayoutAttributes } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return itemCache.filter({ $0.indexPath == indexPath}).first } override var collectionViewContentSize: CGSize { return CGSize(width: contentWidth, height: layoutHeight) } private var contentWidth: CGFloat { guard let collectionView = collectionView else { return 0 } return collectionView.bounds.width } }