103 lines
3.4 KiB
Swift
103 lines
3.4 KiB
Swift
//
|
||
// WaterfallFlowLayout.swift
|
||
// wallpaper_BProject
|
||
//
|
||
// Created by 忆海16 on 2024/8/29.
|
||
//
|
||
|
||
import Foundation
|
||
import UIKit
|
||
|
||
// 自定义瀑布流布局
|
||
class WaterfallFlowLayout: UICollectionViewFlowLayout {
|
||
|
||
let heightInt = [300,320,310,280,290]
|
||
|
||
|
||
// 瀑布流列数
|
||
var numberOfColumns: Int = 2
|
||
|
||
// 单元格的内边距
|
||
var cellPadding: CGFloat = 2
|
||
|
||
// 用于缓存所有计算过的布局属性
|
||
private var cache: [UICollectionViewLayoutAttributes] = []
|
||
|
||
// 用于记录内容的高度
|
||
private var contentHeight: CGFloat = 0
|
||
|
||
// 返回集合视图内容的总尺寸
|
||
override var collectionViewContentSize: CGSize {
|
||
return CGSize(width: collectionView?.bounds.width ?? 0, height: contentHeight)
|
||
}
|
||
|
||
// 准备布局,每次布局无效时都会调用
|
||
override func prepare() {
|
||
// 如果缓存为空,且有 collectionView 存在,则计算布局
|
||
guard cache.isEmpty, let collectionView = collectionView else { return }
|
||
|
||
// 计算每列的宽度
|
||
let columnWidth = collectionView.bounds.width / CGFloat(numberOfColumns)
|
||
|
||
// 初始化每列的 X 偏移量
|
||
var xOffset: [CGFloat] = []
|
||
for column in 0..<numberOfColumns {
|
||
xOffset.append(CGFloat(column) * columnWidth)
|
||
}
|
||
|
||
// 初始化 Y 偏移量
|
||
var column = 0
|
||
var yOffset: [CGFloat] = .init(repeating: 0, count: numberOfColumns)
|
||
|
||
// 遍历所有的项目(items)并计算其布局属性
|
||
for item in 0..<collectionView.numberOfItems(inSection: 0) {
|
||
let indexPath = IndexPath(item: item, section: 0)
|
||
|
||
// 计算随机的单元格高度,可以替换为实际内容的高度
|
||
// let photoHeight = CGFloat(arc4random_uniform(100) + 150)
|
||
// let
|
||
let height = cellPadding * 2 + CGFloat(getRandomheight() ?? 150)
|
||
|
||
// 根据当前列的 X 偏移量和 Y 偏移量计算单元格的 frame
|
||
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
|
||
let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)
|
||
|
||
// 创建布局属性并缓存
|
||
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
|
||
attributes.frame = insetFrame
|
||
cache.append(attributes)
|
||
|
||
// 更新内容高度和当前列的 Y 偏移量
|
||
contentHeight = max(contentHeight, frame.maxY)
|
||
yOffset[column] = yOffset[column] + height
|
||
|
||
// 切换到下一个列
|
||
column = column < (numberOfColumns - 1) ? (column + 1) : 0
|
||
}
|
||
}
|
||
|
||
// 返回指定矩形区域内的所有布局属性
|
||
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||
return cache.filter { $0.frame.intersects(rect) }
|
||
}
|
||
|
||
// 返回指定项目的布局属性
|
||
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
||
return cache[indexPath.item]
|
||
}
|
||
|
||
|
||
func getRandomheight() -> Int? {
|
||
return heightInt.randomElement()
|
||
}
|
||
|
||
}
|
||
|
||
//let randomNumber = Int.random(in: 0...500)
|
||
|
||
func getRandomInt() -> Int?{
|
||
|
||
return Int.random(in: 0...500)
|
||
|
||
}
|