关于UICollectionView的Layout

1,Layout的作用

CollectionView很严格的将数据与布局分隔开来。大多数情况下,你的app只需要提供数据就好,系统提供的布局会为你做很多事情。系统提供的布局已然非常强大,它不仅能够提供多列的网格视图,还能提供平铺视图和圆形视图。当系统提供的布局无法满足你的需求的时候,你还可以自定义布局。

2,Configuring FlowLayout

使用FlowLayout的步骤如下:

  1. 创建FlowLayout对象,并把它赋值给你的CollectionView
  2. 设置cell的宽度和高度
  3. 如果有必要的话,设置LineSpacingItemSpacing
  4. 如果你制定了HeaderViewFooterView,指定它们的size
  5. 设置Layout的滑动方向



为每一个item指定size

  1. 如果所有的itemsize都是固定的,那么就直接用itemSize属性来设置。
  2. 如果你需要为每一个cell指定size,那么你应该在CollectionViewdelegate方法中实现collectionView:layout:sizeForItemAtIndexPath:方法。在布局过程中,Layout对象会将item在竖直方向居中放置,如图。



指定LineSpacingItemSpacing:

  1. 通过设置minimumLineSpacingminimumInteritemSpacing属性。
  2. 通过实现collectionView:layout:minimumLineSpacingForSectionAtIndex:collectionView:layout:minimumInteritemSpacingForSectionAtIndex:这两个delegate方法



指定inset:

  1. 通过sectionInset属性
  2. 通过- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section代理方法

3,Subclassing FlowLayout

虽然FlowLayout功能很强大,但是你也许仍然有需求去自定义FlowLayout。但前提是,你得确保仅通过配置FlowLayout达不到你的目的。

3.1 也许你想为你的Layout添加附加或者装饰视图(supplementary or decoration View)

标准的FlowLayout仅支持HeaderView 和 FooterView,但是不支持DecorationView,如果想实现装饰视图,则需要覆盖下列方法:

  • layoutAttributesForElementsInRect: (required)
  • layoutAttributesForItemAtIndexPath: (required)
  • layoutAttributesForSupplementaryViewOfKind:atIndexPath: (to support new supplementary views)
  • layoutAttributesForDecorationViewOfKind:atIndexPath: (to support new decoration views)

3.2 也许你想调整FlowLayout的布局属性

覆盖layoutAttributesForElementsInRect:这个方法,在这个方法的实现中,先调用super方法,在更改属性,最后将属性返回。

实例

//该方法返回一个UICollectionViewLayoutAttributes对象数组,其中包含了每一个单元格的布局属性
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes *attributes in array) {
        CGRect frame = attributes.frame;
        float distance = fabs(self.collectionView.contentOffset.x  + self.collectionView.contentInset.left - frame.origin.x);
        float scale = 1 * MIN(MAX(1 - distance / self.collectionView.bounds.size.width, 0.8), 1);
        attributes.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return array;
} 

3.3 也许你想添加新的布局属性

  1. 继承UICollectionViewLayoutAttributes,实现自己的LayoutAttributes,然后可以添加任何你需要的布局信息作为它的属性。
  2. 在自定义的FlowLayout中,覆盖layoutAttributesClass方法

3.4 也许你想自定义insert或者delete的动画

insert或者delete某个cell的时候,系统提供了默认动画。如果你想实现自己的动画,可以通过覆盖一下方法来实现:

  • initialLayoutAttributesForAppearingItemAtIndexPath:
  • initialLayoutAttributesForAppearingSupplementaryElementOfKind:atIndexPath:
  • initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:
  • finalLayoutAttributesForDisappearingItemAtIndexPath:
  • finalLayoutAttributesForDisappearingSupplementaryElementOfKind:atIndexPath:
  • finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath:

4,自定义Layout[]

4.1

在创建自定义的layout之前,你需要知道UICollectionViewFlowLayout提供的很多特性已经经过优化以满足多种常用的layout。除非是如下情况,否则不建议自定义:

  1. 你所想实现的外观并不是网格或者line-based breaking布局(items排成一行直到行满,再继续往下一行上去排,直到所有items都排列完成),或者必须要在多个方向上都可以滚动
  2. 需要频繁地改变所有 Cell 的位置,以致于创建自定义layout比修改现有flow layout工作量更省

4.2 继承UICollectionViewLayout

继承UICollectionViewLayout之后只需要重载几个提供布局核心特性的方法,其他方法只需按情况重载即可,核心特性如下:

  1. 指定可滚动内容区域的size
  2. 为布局中的每个Cellview提供属性对象

你可能感兴趣的:(关于UICollectionView的Layout)