Swift版-CollectionView瀑布流框架搭建

首先聲明該Swift版是根據(jù)iOS-CollectionView瀑布流框架搭建這篇文章的OC版思路來(lái)實(shí)現(xiàn)的,
首先來(lái)個(gè)效果圖:

瀑布流布局

思路:思路的話請(qǐng)看這iOS-CollectionView瀑布流框架搭建
這里就直接上代碼啦

定義如下屬性:

class GKWaterViewLayout: UICollectionViewLayout {
    // MARK: - 定義屬性
    weak var delegate : GKWaterViewLayoutDelegate?
    /// 總列數(shù)
    var colCount : Int {
        return (delegate?.cloumnCountInWaterFlowLayout(self))!
        }
    /// 列間距
    var colMargin: CGFloat {
        return (delegate?.columMarginInWaterFlowLayout(self))!
    }
    /// 行間距
    var rowMargin: CGFloat {
        return (delegate?.rowMarginInWaterFlowLayout(self))!
    }
    /// 當(dāng)前內(nèi)邊距
    var currentEdgeInsets: UIEdgeInsets {
        return (delegate?.edgeInsetInWaterFlowLayout(self))!
    }
    /// 布局屬性數(shù)組
    private lazy var attrsArray = [UICollectionViewLayoutAttributes]()
    /// 存放所有列的當(dāng)前高度
    private lazy var colHeights = [CGFloat]()
}

聲明代理協(xié)議

  • 必須實(shí)現(xiàn)
// TODO:  由代理返回每一個(gè)cell的高度
protocol GKWaterViewLayoutDelegate: class {

    /// 返回每一個(gè)cell的高度
    func waterLayout(waterFlowLayout: GKWaterViewLayout,heightForRowAtIndex index: Int , itemWidth: CGFloat) -> CGFloat;
}
  • 可選實(shí)現(xiàn)
    • 代理未實(shí)現(xiàn)就使用默認(rèn)值
// MARK: - 可選實(shí)現(xiàn)
extension GKWaterViewLayoutDelegate {
    /// 決定cell的列數(shù)
    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)
    }
}

重寫布局相關(guān)方法

/// 布局相關(guān)
extension GKWaterViewLayout {
    
    override func prepareLayout() {
        super.prepareLayout()
        
        colHeights.removeAll()
        for _ in 0..<colCount {
            colHeights.append(currentEdgeInsets.top)
        }
        let count = collectionView?.numberOfItemsInSection(0)
        attrsArray.removeAll()
        
        for i in 0..<count! {
            let indexPath = NSIndexPath(forRow: i, inSection: 0)
            // 獲取indexPath對(duì)應(yīng)cell的布局屬性
            let attr = self.layoutAttributesForItemAtIndexPath(indexPath)
            attrsArray.append(attr!)
        }
    }

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
        let attr = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
        var destCol = 0
        var minColHeight = colHeights.first
        // 找出高度最短的那一列
        for i in 0..<colCount {
            let colHeight = colHeights[i]
            if minColHeight > colHeight {
                minColHeight = colHeight
                destCol = i
            }
        }
        // 計(jì)算每個(gè)item寬度
        // (collectionView寬度 - 左右間距 - 列間距) / 總列數(shù)
        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
    }
    /// 這個(gè)方法返回值是個(gè)數(shù)組,存放的是UICollectionViewLayoutAttributes對(duì)象
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return attrsArray
    }
    /// 決定collectionView的可滾動(dòng)范圍
    override func collectionViewContentSize() -> CGSize {
        var maxHeight: CGFloat = colHeights.first!
        for i in 0..<colCount {
            let value: CGFloat = colHeights[i]
            if maxHeight < value {
                maxHeight = value
            }
        }
        return CGSize(width: 0, height: maxHeight + currentEdgeInsets.bottom)
    }
}

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

如果好用,請(qǐng)點(diǎn)上star,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,198評(píng)論 4 61
  • 【我讀】人在一起,只是團(tuán)伙!心在一起,才是團(tuán)隊(duì)! 【我思】在我們的日常工作過(guò)程中,經(jīng)常會(huì)發(fā)現(xiàn)人很多,大家看起來(lái)都在...
    四十剛好閱讀 173評(píng)論 0 0
  • 有個(gè)Ubuntu新手問(wèn)我這個(gè)問(wèn)題,于是我寫了這個(gè)回答,放在知乎上。現(xiàn)在放在jianshu上。這也算是我那篇Wind...
    無(wú)與童比閱讀 5,900評(píng)論 0 4
  • 出新緣是不停尋,入意感知滋味深。 心底詩(shī)情豁靈境,眼前風(fēng)色散煩襟。 高懷若可寄天地,遠(yuǎn)志無(wú)須論古今。 歲月留人時(shí)漸...
    雪窗_武立之閱讀 480評(píng)論 0 5
  • aspcms修改分頁(yè)提示樣式 找到inc/AspCms_Language.asp修改里面的文字就可以了,如:str...
    您好小耗子閱讀 1,811評(píng)論 0 0