【iOS】WaterfallLayout 自帶過渡效果的瀑布流布局

Demo地址

自帶過渡效果的UICollectionView瀑布流布局。

Feature:
    ? 自帶過渡效果;
    ? 可自定義列數(shù)、間距等屬性;
    ? 適配橫豎屏;
    ? 提供異步刷新;
    ? 兼容 OC & Swift;
    ? API簡單易用。

效果

  • 整體刷新效果
  • 列數(shù)變化效果
  • 增/刪/改效果
  • 適配橫豎屏

使用

  1. 只需將WaterfallLayout.swift文件拖進(jìn)項(xiàng)目

  2. 初始化waterfallLayoutcollectionView并成為其代理

let waterfallLayout = WaterfallLayout()
waterfallLayout.delegate = self

let collectionView = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: waterfallLayout)
collectionView.delegate = self
collectionView.dataSource = self
view.addSubview(collectionView)
  1. 實(shí)現(xiàn)waterfallLayout的代理方法,搞定
extension ViewController: WaterfallLayoutDelegate {
    /// 提供item的下標(biāo)和(根據(jù)列數(shù)和間距得出)的寬度,需代理返回對應(yīng)item的高度
    func waterfallLayout(_ waterfallLayout: WaterfallLayout, heightForItemAtIndex index: Int, itemWidth: CGFloat) -> CGFloat {
        // 具體可參考Demo
        let girl = girls[index]
        return itemWidth / girl.whRatio
    }
    
    ///【可選】cell的總列數(shù)
    func colCountInWaterFlowLayout(_ waterfallLayout: WaterfallLayout) -> Int {
        4
    }
    
    ///【可選】cell的列間距
    func colMarginInWaterFlowLayout(_ waterfallLayout: WaterfallLayout) -> CGFloat {
        5
    }
    
    ///【可選】cell的行間距
    func rowMarginInWaterFlowLayout(_ waterfallLayout: WaterfallLayout) -> CGFloat {
        5
    }
    
    ///【可選】collectionView的內(nèi)容間距
    func edgeInsetsInWaterFlowLayout(_ waterfallLayout: WaterfallLayout) -> UIEdgeInsets {
        UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
    }
}
  1. 刷新布局
// 帶動畫刷新:使用自定義動畫包裹c(diǎn)ollectionView的刷新操作
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.88, initialSpringVelocity: 1) {
    self.collectionView.performBatchUpdates {
        self.collectionView.reloadSections(IndexSet(integer: 0))
    }
}

// 不帶動畫刷新
collectionView.reloadData()

Tips

  1. 目前僅支持UICollectionViewCell單Section的布局,也就是說不支持Section頭、Section尾和多個Section的情況;

  2. 當(dāng)數(shù)據(jù)量龐大時,可使用異步刷新:

waterfallLayout.asyncUpdateLayout(itemTotal: girls.count) { [weak self] index, itemWidth in
    // 提供item的下標(biāo)和(根據(jù)列數(shù)和間距得出)的寬度,返回對應(yīng)item的高度
    guard let self = self else { return 1 }
    let girl = self.girls[index]
    return itemWidth / girl.whRatio
} completion: { [weak self] in
    // 刷新布局
    guard let self = self else { return }
    UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.88, initialSpringVelocity: 1) {
        self.collectionView.performBatchUpdates {
            self.collectionView.reloadSections(IndexSet(integer: 0))
        }
    }
}

PS:目前已做了初步優(yōu)化,即便不使用異步刷新,在展示和滑動大量數(shù)據(jù)的列表(如用戶相冊)時也能保持頁面流暢:

  • 后續(xù)迭代將不斷優(yōu)化!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容