UICollectionViewLayout佈局詳解
阿新 • • 發佈:2019-12-25
簡介
Supplementary Views 追加檢視 (類似Header或者Footer)
Decoration 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的例項中包含了諸如邊框,中心點,大小,形狀,透明度,層次關係和是否隱藏等資訊。
- 一個cell對應一個UICollectionViewLayoutAttributes物件
- 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來生成更新後的佈局。
複製程式碼