自定義的UICollectionViewLayout簡介
UICollectionViewLayout的功能為向UICollectionView提供布局信息,不僅包括cell的布局信息,也包括追加視圖和裝飾視圖的布局信息。
實現一個自定義layout的常規做法是繼承UICollectionViewLayout類,然后重載下列方法:
- -(CGSize)collectionViewContentSize
- 返回collectionView的內容的尺寸
- -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
- 返回rect中的所有的元素的布局屬性
- 返回的是包含UICollectionViewLayoutAttributes的NSArray
- UICollectionViewLayoutAttributes可以是cell,追加視圖或裝飾視圖的信息,通過不同的UICollectionViewLayoutAttributes初始化方法可以得到不同類型的UICollectionViewLayoutAttributes:
- layoutAttributesForCellWithIndexPath:
- layoutAttributesForSupplementaryViewOfKind:withIndexPath:
- 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到其他地方)時,將重新計算需要的布局信息。
另外需要了解的是,在初始化一個UICollectionViewLayout實例后,會有一系列准備方法被自動調用,以保證layout實例的正確。
- 首先,-(void)
prepareLayout將被調用,默認下該方法什么沒做,但是在自己的子類實現中,一般在該方法中設定一些必要的layout的結構和初始需要的參數等。 - 之后,-(CGSize)
collectionViewContentSize將被調用,以確定collection應該占據的尺寸。注意這里的尺寸不是指可視部分的尺寸,而應該是所有內容所占的尺寸。collectionView的本質是一個scrollView,因此需要這個尺寸來配置滾動行為。 - 接下來-(NSArray *)
layoutAttributesForElementsInRect:(CGRect)rect被調用,這個沒什么值得多說的。初始的layout的外觀將由該方法返回的UICollectionViewLayoutAttributes來決定。 - 另外,在需要更新layout時,需要給當前layout發送 -invalidateLayout,該消息會立即返回,並且預約在下一個loop的時候刷新當前layout,這一點和UIView的setNeedsLayout方法十分類似。在-invalidateLayout后的下一個collectionView的刷新loop中,又會從prepareLayout開始,依次再調用-collectionViewContentSize和-layoutAttributesForElementsInRect來生成更新后的布局。
