效果图
实现思路
UICollectionView的精髓就是UICollectionViewLayout。UICollectionViewLayout决定了UICollectionView是如何显示在界面上的。因此我们需要自定义一个UICollectionViewLayout 的子类,在子类里面重写生成布局的方法,创建我们自己需要的布局
实现原理
重写- (void)prepareLayout进行提前创建布局
重写- (CGSize)collectionViewContentSize返回内容的大小
重写 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect方法返回rect中所有元素的布局属性,返回的是一个数组
重写 - (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;当边界发生改变时,是否应该刷新。
注意:其中
- (void)prepareLayout
- (CGSize)collectionViewContentSize
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
这三个方法是必须要重写的,后面的方法可以选择性重写,因为最终collectionView 还是根据 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect 方法来进行展示布局的,
而重写 prepareLayout是因为创建布局的时机 需要提前到 prepareLayout 里面。
而collectionViewContentSize 是返回内容宽和高的,也必须重写