自定義的UICollectionViewLayout
UICollectionViewLayout的功能為向UICollectionView提供布局信息首繁,不僅包括cell的布局信息作郭,也包括追加視圖和裝飾視圖的布局信息。實(shí)現(xiàn)一個(gè)自定義layout的常規(guī)做法是繼承UICollectionViewLayout類弦疮,然后重載下列方法:
-(CGSize)collectionViewContentSize
返回collectionView的內(nèi)容的尺寸
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
返回rect中的所有的元素的布局屬性
返回的是包含UICollectionViewLayoutAttributes的NSArray
UICollectionViewLayoutAttributes可以是cell夹攒,追加視圖或裝飾視圖的信息,通過不同的UICollectionViewLayoutAttributes初始化方法可以得到不同類型的UICollectionViewLayoutAttributes:
layoutAttributesForCellWithIndexPath:
layoutAttributesForSupplementaryViewOfKind:withIndexPath:
layoutAttributesForDecorationViewOfKind:withIndexPath:
-(UICollectionViewLayoutAttributes)layoutAttributesForItemAtIndexPath:(NSIndexPath)indexPath
返回對應(yīng)于indexPath的位置的cell的布局屬性
-(UICollectionViewLayoutAttributes)layoutAttributesForSupplementaryViewOfKind:(NSString)kind atIndexPath:(NSIndexPath *)indexPath
返回對應(yīng)于indexPath的位置的追加視圖的布局屬性挂捅,如果沒有追加視圖可不重載
-(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath)indexPath
返回對應(yīng)于indexPath的位置的裝飾視圖的布局屬性芹助,如果沒有裝飾視圖可不重載
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
當(dāng)邊界發(fā)生改變時(shí),是否應(yīng)該刷新布局闲先。如果YES則在邊界變化(一般是scroll到其他地方)時(shí)状土,將重新計(jì)算需要的布局信息。
另外需要了解的是伺糠,在初始化一個(gè)UICollectionViewLayout實(shí)例后蒙谓,會(huì)有一系列準(zhǔn)備方法被自動(dòng)調(diào)用斟赚,以保證layout實(shí)例的正確亭姥。
首先烟勋,-(void)prepareLayout將被調(diào)用掂榔,默認(rèn)下該方法什么沒做簿盅,但是在自己的子類實(shí)現(xiàn)中药磺,一般在該方法中設(shè)定一些必要的layout的結(jié)構(gòu)和初始需要的參數(shù)等牺丙。
之后吆玖,-(CGSize) collectionViewContentSize將被調(diào)用午绳,以確定collection應(yīng)該占據(jù)的尺寸置侍。注意這里的尺寸不是指可視部分的尺寸,而應(yīng)該是所有內(nèi)容所占的尺寸。collectionView的本質(zhì)是一個(gè)scrollView蜡坊,因此需要這個(gè)尺寸來配置滾動(dòng)行為杠输。
接下來-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect被調(diào)用,這個(gè)沒什么值得多說的秕衙。初始的layout的外觀將由該方法返回的UICollectionViewLayoutAttributes來決定蠢甲。
另外,在需要更新layout時(shí)据忘,需要給當(dāng)前l(fā)ayout發(fā)送 -invalidateLayout鹦牛,該消息會(huì)立即返回,并且預(yù)約在下一個(gè)loop的時(shí)候刷新當(dāng)前l(fā)ayout若河,這一點(diǎn)和UIView的setNeedsLayout方法十分類似能岩。在-invalidateLayout后的下一個(gè)collectionView的刷新loop中,又會(huì)從prepareLayout開始萧福,依次再調(diào)用-collectionViewContentSize和-layoutAttributesForElementsInRect來生成更新后的布局拉鹃。