UICollectionViewFlowLayout备忘录

来源:互联网 发布:淘宝网站首页源代码 编辑:程序博客网 时间:2024/05/20 23:56

UICollectionView的结构回顾

CollectionView的构成,我们能看到的有三个部分:

CellsSupplementary Views 追加视图 (类似Header或者Footer)Decoration Views 装饰视图 (用作背景展示)

由两个方面对UICollectionView进行支持:
1. 和tableView一样,即提供数据的UICollectionViewDataSource以及处理用户交互的UICollectionViewDelegate。
2. 对于cell的样式和组织方式,由于collectionView比tableView要复杂得多,因此没有按照类似于tableView的style的方式来定义,而是专门使用了一个类来对collectionView的布局和行为进行描述,这就是UICollectionViewLayout。

UICollectionViewLayoutAttributes

UICollectionViewLayoutAttributes是一个非常重要的类,先来看看property列表:

// 边框@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

和DataSource的行为十分类似,当UICollectionView在获取布局时将针对每一个indexPath的部件(包括cell,追加视图和装饰视图),向其上的UICollectionViewLayout实例询问该部件的布局信息,这个布局信息,就以UICollectionViewLayoutAttributes的实例的方式给出。

自定义的UICollectionViewLayout

UICollectionViewLayout的功能为向UICollectionView提供布局信息,不仅包括cell的布局信息,也包括追加视图和装饰视图的布局信息。实现一个自定义layout的常规做法是继承UICollectionViewLayout类,然后重载下列方法:

-(CGSize)collectionViewContentSize// 返回collectionView的内容的尺寸-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect// 返回rect中的所有的元素的布局属性//返回的是包含UICollectionViewLayoutAttributes的NSArray

UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttributes:

(nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;// 返回对应于indexPath的位置的cell的布局属性(nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;// 返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载(nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;// 返回对应于indexPath的位置的装饰视图的布局属性,如果没有装饰视图可不重载
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds//当边界发生改变时,是否应该刷新布局。如果YES则在边界变化(一般是scroll到其他地方)时,将重新计算需要的布局信息。/** *  只要显示的边界发生改变就重新布局: 内部会重新调用prepareLayout和layoutAttributesForElementsInRect方法获得所有cell的布局属性 */

初始化UICollectionViewLayout过程

在初始化一个UICollectionViewLayout实例后,会有一系列准备方法被自动调用,以保证layout实例的正确。
1 -(void)prepareLayout将被调用,默认下该方法什么没做,但是在自己的子类实现中,一般在该方法中设定一些必要的layout的结构和初始需要的参数等。

2 -(CGSize) collectionViewContentSize将被调用,以确定collection应该占据的尺寸。
注意:这里的尺寸不是指可视部分的尺寸,而应该是所有内容所占的尺寸。collectionView的本质是一个scrollView,因此需要这个尺寸来配置滚动行为。

3 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect被调用,这个没什么值得多说的。初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。

4 在需要更新layout时,需要给当前layout发送 -invalidateLayout,该消息会立即返回,并且预约在下一个loop的时候刷新当前layout,这一点和UIView的setNeedsLayout方法十分类似。在-invalidateLayout后的下一个collectionView的刷新loop中,又会从prepareLayout开始,依次再调用-collectionViewContentSize-layoutAttributesForElementsInRect来生成更新后的布局。

0 0
原创粉丝点击