# 瀑布流實現Demo

本文僅供自己學習總結,參考!

  • 對於瀑布流,主要就是對UICollectionView的flowLayout的熟練應用,關於UIcollectionView的佈局詳細講解,可以查閱這篇文章
  • 當UICollectionView需要刷新時,(放到屏幕上或需要reloadData)或者被標記爲需要重新計算佈局(調用了layout對象的invalidateLayout方法)時,UICollectionView就會向佈局對象請求一系列的方法:
  1. 首先會調用prepareLayout方法,在此方法中儘可能將後續佈局時需要用到的前置計算處理好,每次重新佈局都是從此方法開始。
 /**
  
  // The collection view calls -prepareLayout again after layout is invalidated and before requerying the layout information.
  
  //集合視圖在佈局失效後,在請求佈局信息之前再次調用-prepareLayout。
  首先會調用prepareLayout方法,在此方法中儘可能將後續佈局時需要用到的前置計算處理好,每次重新佈局都是從此方法開始
  
  **/
#pragma mark 準備佈局
- (void)prepareLayout
{
    //初始化最大高度數組
    //初始化item佈局屬性數組
    //獲取最大的y值
}

  1. 調用layoutAttributesForElementsInRect:方法,計算rect內相應的佈局,並返回一個裝有UICollectionViewLayoutAttributes的數組,Attributes 跟所有Item一一對應,UICollectionView就是根據這個Attributes來對Item進行佈局,並當新的Rect區域滾動進入屏幕時再次請求此方法。
//MARK: 返回rect 範圍內的item的佈局數組(這個方法會頻繁調用)

- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    return  self.attrsArray;
}

2.1 通過layoutAttributesForItemAtIndexPath方法獲取item的佈局屬性,在改方法中就要計算出cell的 x, y, width, height


//MARK: 返回indexPath位置的item佈局屬性
/** 註釋
 //使用此方法可檢索特定項的佈局信息。您應該始終使用此方法,而不是直接查詢佈局對象。
 Use this method to retrieve the layout information for a particular(特定的) item. You should always use this method instead of querying the layout object directly.
 */
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //計算一個cell的寬度
    //計算當前item應該放在第幾列(就是計算那一列高度最短)
    /**
    默認是第0列
    計算的方式就是,遍歷裝有所有高度的數組,讓所有的元素和temp去比較,當temp大於元素時,將這個元素賦值給這個temp,找到高度最小的列
    */
    
    //計算得到 x,y,width, height
    
    return attrs;
}

  1. 調用collectionViewContentSize方法,根據第一點中的計算來返回所有內容的滾動區域大小。

ps:CGSize中爲啥x的值爲0 ?
answer:
//豎向瀑布流 item等寬不等高
/**
如果是等寬不等高,size的 x可以是任意值,我測試了下,都沒有問題
我看有大佬寫的是 self.collectionView.bounds.size.width,也是可以的

 如果是等高不等寬的時候,寬可以爲一個固定值
 可以看下這個大佬的文章 https://www.jianshu.com/p/9fafd89c97ad
 */
//MARK: 返回collectionViewView的contentSize

- (CGSize)collectionViewContentSize
{
    CGSize size =  CGSizeMake(0, self.maxY + [self edgeInsets].bottom);
    NSLog(@"__ssss__%@", NSStringFromCGSize(size));
    return size;
    
}

附上Demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章