1. 程式人生 > IOS開發 >UICollectionViewLayout佈局詳解

UICollectionViewLayout佈局詳解

簡介

Supplementary Views 追加檢視 (類似Header或者FooterDecoration Views 裝飾檢視 (用作背景展示)
複製程式碼

對於cell的樣式和組織方式,由於collectionView比tableView要複雜得多,因此沒有按照類似於tableView的style的方式來定義,而是專門使用了一個類來對collectionView的佈局和行為進行描述,這就是UICollectionViewLayout

而我們主要講UICollectionViewLayout,因為這不僅是collectionView和tableView的最重要求的區別,也是整個UICollectionView的精髓所在。

UICollectionViewLayoutAttributes

@property (nonatomic) CGRect frame
@property (nonatomic) CGPoint center
@property (nonatomic) CGSize size
@property (nonatomic) CATransform3D transform3D
@property (nonatomic) CGFloat alpha
@property (nonatomic) NSInteger zIndex
@property (nonatomic,getter=isHidden) BOOL hidden
複製程式碼

可以看到,UICollectionViewLayoutAttributes的例項中包含了諸如邊框,中心點,大小,形狀,透明度,層次關係和是否隱藏等資訊。

  1. 一個cell對應一個UICollectionViewLayoutAttributes物件
  2. UICollectionViewLayoutAttributes物件決定了cell的擺設位置(frame)

自定義UICollectionViewLayout

UICollectionViewLayout的功能為向UICollectionView提供佈局資訊,不僅包括cell的佈局資訊,也包括追加檢視和裝飾檢視的佈局資訊。實現一個自定義layout的常規做法是繼承UICollectionViewLayout類,然後過載下列方法:

-(void)prepareLayout
prepare方法被自動呼叫,以保證layout例項的正確。

-(CGSize)collectionViewContentSize
返回collectionView的內容的尺寸

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
 1. 返回rect中的所有的元素的佈局屬性
 2. 返回的是包含UICollectionViewLayoutAttributes的NSArray
 3. UICollectionViewLayoutAttributes可以是cell,追加檢視或裝飾檢視的資訊,通過不同的UICollectionViewLayoutAttributes初始化方法可以得到不同型別的UICollectionViewLayoutAttributes:
  1)layoutAttributesForCellWithIndexPath:
  2)layoutAttributesForSupplementaryViewOfKind:withIndexPath:
  3)layoutAttributesForDecorationViewOfKind:withIndexPath:

-(UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath
返回對應於indexPath的位置的cell的佈局屬性

-(UICollectionViewLayoutAttributes )layoutAttributesForSupplementaryViewOfKind:(NSString )kind atIndexPath:(NSIndexPath *)indexPath
返回對應於indexPath的位置的追加檢視的佈局屬性,如果沒有追加檢視可不過載

-(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath )indexPath
返回對應於indexPath的位置的裝飾檢視的佈局屬性,如果沒有裝飾檢視可不過載

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
當邊界發生改變時,是否應該重新整理佈局。如果YES則在邊界變化(一般是scroll到其他地方)時,將重新計算需要的佈局資訊。
呼叫順序
複製程式碼

呼叫順序

1)-(void)prepareLayout  
  a. collection view 只會在第一次layout的時候呼叫一次`-prepareLayout`,作為第一次通知layout例項物件的訊息
  b. collection view 會在 layout 物件 invalidated 之後並且requerying之前再次呼叫
  c. 繼承自UICollectionViewLayout都需要重寫這個方法,一般都是在這個方法裡面準備好`layoutAttributesForElements(in:)`這個方法要使用到的`UICollectionViewLayoutAttributes`陣列。
  
2)  -(CGSize) collectionViewContentSize 
  a. 確定collectionView的所有內容的尺寸
  b. 每一次移動collection view時都會呼叫這個方法,並且這個方法會被呼叫多次

3)-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
  初始的layout的外觀將由該方法返回的UICollectionViewLayoutAttributes來決定。

4)在需要更新layout時,需要給當前layout傳送 
     1)-invalidateLayout, 該訊息會立即返回,並且預約在下一個loop的時候重新整理當前layout
     2)-prepareLayout,
     3)依次再呼叫-collectionViewContentSize和-layoutAttributesForElementsInRect來生成更新後的佈局。
複製程式碼