Swift版-CollectionView瀑布流框架搭建

首先声明该Swift版是根据iOS-CollectionView瀑布流框架搭建这篇文章的OC版思路来实现的,
首先来个效果图:

Swift版-CollectionView瀑布流框架搭建_第1张图片
瀑布流布局

思路:思路的话请看这iOS-CollectionView瀑布流框架搭建
这里就直接上代码啦

定义如下属性:

class GKWaterViewLayout: UICollectionViewLayout {
    // MARK: - 定义属性
    weak var delegate : GKWaterViewLayoutDelegate?
    /// 总列数
    var colCount : Int {
        return (delegate?.cloumnCountInWaterFlowLayout(self))!
        }
    /// 列间距
    var colMargin: CGFloat {
        return (delegate?.columMarginInWaterFlowLayout(self))!
    }
    /// 行间距
    var rowMargin: CGFloat {
        return (delegate?.rowMarginInWaterFlowLayout(self))!
    }
    /// 当前内边距
    var currentEdgeInsets: UIEdgeInsets {
        return (delegate?.edgeInsetInWaterFlowLayout(self))!
    }
    /// 布局属性数组
    private lazy var attrsArray = [UICollectionViewLayoutAttributes]()
    /// 存放所有列的当前高度
    private lazy var colHeights = [CGFloat]()
}

声明代理协议

  • 必须实现
// TODO:  由代理返回每一个cell的高度
protocol GKWaterViewLayoutDelegate: class {

    /// 返回每一个cell的高度
    func waterLayout(waterFlowLayout: GKWaterViewLayout,heightForRowAtIndex index: Int , itemWidth: CGFloat) -> CGFloat;
}
  • 可选实现
    • 代理未实现就使用默认值
// MARK: - 可选实现
extension GKWaterViewLayoutDelegate {
    /// 决定cell的列数
    func cloumnCountInWaterFlowLayout(waterFlowLayout: GKWaterViewLayout) -> Int {
        return 3
    }
    
    /// 决定cell 的列间距
    func columMarginInWaterFlowLayout(waterFlowLayout: GKWaterViewLayout) -> CGFloat {
        return 10.0
    }

    /// 决定cell 的行间距
    func rowMarginInWaterFlowLayout(waterFlowLayout: GKWaterViewLayout) -> CGFloat {
        return 10.0
    }

    /// 决定cell的边缘间距
    func edgeInsetInWaterFlowLayout(waterFlowLayout: GKWaterViewLayout) -> UIEdgeInsets {
        return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    }
}

重写布局相关方法

/// 布局相关
extension GKWaterViewLayout {
    
    override func prepareLayout() {
        super.prepareLayout()
        
        colHeights.removeAll()
        for _ in 0.. UICollectionViewLayoutAttributes? {
        let attr = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
        var destCol = 0
        var minColHeight = colHeights.first
        // 找出高度最短的那一列
        for i in 0.. colHeight {
                minColHeight = colHeight
                destCol = i
            }
        }
        // 计算每个item宽度
        // (collectionView宽度 - 左右间距 - 列间距) / 总列数
        let width = (collectionView?.frame.width)! - currentEdgeInsets.left - currentEdgeInsets.right
        let w = (width - CGFloat(colCount - 1) * colMargin) / CGFloat(colCount)
        // 使用代理决定外部cell的高度
        let h = delegate?.waterLayout(self, heightForRowAtIndex: indexPath.item, itemWidth: w)
        let x = currentEdgeInsets.left + CGFloat(destCol) * (w + colMargin)
        var y = minColHeight
        if y != currentEdgeInsets.top {
            y = y! + rowMargin
        }
        attr.frame = CGRect(x: x, y: y!, width: w, height: h!)
        colHeights[destCol] = y! + h!
        return attr
    }
    /// 这个方法返回值是个数组,存放的是UICollectionViewLayoutAttributes对象
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return attrsArray
    }
    /// 决定collectionView的可滚动范围
    override func collectionViewContentSize() -> CGSize {
        var maxHeight: CGFloat = colHeights.first!
        for i in 0..

到此,CollectionView瀑布流框架搭建完成了!
Demo下载地址

如果好用,请点上star,谢谢

你可能感兴趣的:(Swift版-CollectionView瀑布流框架搭建)