guard let collectionView = collectionView else { return } let columnsRange = 0 ..< configuration.numberOfColumns var columns = columnsRange.map { _ in 0 } var attributesCollection = [UICollectionViewLayoutAttributes]() var yOffset = configuration.topOffset if let height = delegate.adsGridViewLayout(self, heightForHeaderViewInCollectionView: collectionView) { let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, with: IndexPath(item: 0, section: 0)) attributes.frame = CGRect(x: 0, y: 0, width: collectionView.frame.size.width, height: height) attributesCollection.append(attributes) yOffset += height } for index in 0 ..< numberOfItems { let columnIndex = indexOfLowestValue(in: columns) let xOffset = xOffsetForItemInColumn(itemWidth: itemWidth, columnIndex: columnIndex) let topPadding = configuration.numberOfColumns > index ? yOffset : 0.0 let verticalOffset = CGFloat(columns[columnIndex]) + topPadding let indexPath = IndexPath(item: index, section: 0) let itemHeight = delegate.adsGridViewLayout(self, heightForItemWithWidth: itemWidth, at: indexPath) columns[columnIndex] = Int(verticalOffset + itemHeight + configuration.columnSpacing) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) attributes.frame = CGRect(x: xOffset, y: verticalOffset, width: itemWidth, height: itemHeight) attributesCollection.append(attributes) } itemAttributes.append(contentsOf: attributesCollection) }