UICollectionViewLayout的功能为向UICollectionView提供布局信息。实现一个自定义layout的常规做法是继承UICollectionViewLayout类,然后重载下列方法:
1 /// UICollectionViewLayout的方法 2 /** 3 返回collectionView的内容的尺寸(注意:这里的尺寸不是可视部分的尺寸,应该所有内容的尺寸,以便系统来配置UICollectionView滚动行为) 4 */ 5 - (CGSize)collectionViewContentSize; 6 7 /** 8 布局之前,自动调用(子类重写必须调用该方法的父类方法,一般在该方法中设计一些初始需要的参数等) 9 */ 10 - (void)prepareLayout; 11 12 /** 13 返回rect中的所有的元素的布局属性<数组内都是UICollectionViewLayoutAttributes的实例对象>,根据UICollectionViewLayoutAttributes初始化方法不同可以得到UICollectionView不同组件的信息(UICollectionViewLayoutAttributes初始化方法在下面给出) 14 */ 15 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect; 16 17 /** 18 返回对应于indexPath的位置的cell的布局属性 19 */ 20 - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath; 21 22 /** 23 返回对应于indexPath的位置的追加视图的布局属性(没有追加视图可不重载) 24 */ 25 - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath; 26 27 /** 28 返回对应于indexPath的位置的装饰视图的布局属性(没有装饰视图可不重载) 29 */ 30 - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath; 31 32 /** 33 需要更新Layout之前,需要调用该方法(是否允许重新计算需要的布局信息)一般设为YES. 34 */ 35 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
UICollectionViewLayoutAttributes初始化方法:
1 /// UICollectionViewLayoutAttributes初始化方法: 2 /** 3 得到cell的UICollectionViewLayoutAttributes的实例,根据实例对象可以得到cell的信息 4 */ 5 + (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath; 6 7 /** 8 得到的是头部或尾部的UICollectionViewLayoutAttributes的实例,根据实例对象可以得到头部或尾部的信息 9 */ 10 + (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath; 11 12 /** 13 得到的是装饰图的UICollectionViewLayoutAttributes的实例,根据实例对象可以得到装饰图的信息 14 */ 15 + (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath *)indexPath;
另外我们需要了解,在初始化一个UICollectionViewLayout实例后,会有一系列准备方法被自动调用,以保证layout实例的正确。
1 /** 2 首先,该方法将被调用,默认下该方法什么没做,但是在自己的子类实现中,一般在该方法中设定一些必要的layout的结构和初始需要的参数等。 3 */ 4 - (void)prepareLayout; 5 6 7 /** 8 然后,该方法将被调用,以确定collection应该占据的尺寸。注意这里的尺寸不是指可视部分的尺寸,而应该是所有内容所占的尺寸。collectionView的本质是一个scrollView,因此需要这个尺寸来配置滚动行为。 9 */ 10 - (CGSize) collectionViewContentSize; 11 12 13 /** 14 接下来,该方法被调用。初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。 15 */ 16 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect; 17 18 19 /** 20 另外,在需要更新layout时,需要给当前layout发送 -invalidateLayout,该消息会立即返回,并且预约在下一个loop的时候刷新当前layout,这一点和UIView的setNeedsLayout方法十分类似。在-invalidateLayout后的下一个collectionView的刷新loop中,又会从prepareLayout开始,依次再调用-collectionViewContentSize和-layoutAttributesForElementsInRect来生成更新后的布局。 21 */ 22 - (void)invalidateLayout; 23 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
尊重作者劳动成果,转载请注明: 【kingdev】