关于UICollectionView的Layout
2016-05-27 本文已影响1059人
a5da958858b8
1,Layout的作用
CollectionView
很严格的将数据与布局分隔开来。大多数情况下,你的app只需要提供数据就好,系统提供的布局会为你做很多事情。系统提供的布局已然非常强大,它不仅能够提供多列的网格视图,还能提供平铺视图和圆形视图。当系统提供的布局无法满足你的需求的时候,你还可以自定义布局。
2,Configuring FlowLayout
使用FlowLayout
的步骤如下:
- 创建
FlowLayout
对象,并把它赋值给你的CollectionView
。 - 设置
cell
的宽度和高度 - 如果有必要的话,设置
LineSpacing
和ItemSpacing
。 - 如果你制定了
HeaderView
和FooterView
,指定它们的size
。 - 设置
Layout
的滑动方向
为每一个item
指定size
:
- 如果所有的
item
的size
都是固定的,那么就直接用itemSize
属性来设置。 - 如果你需要为每一个
cell
指定size
,那么你应该在CollectionView
的delegate
方法中实现collectionView:layout:sizeForItemAtIndexPath:
方法。在布局过程中,Layout
对象会将item
在竖直方向居中放置,如图。
指定LineSpacing
和ItemSpacing
:
- 通过设置
minimumLineSpacing
和minimumInteritemSpacing
属性。 - 通过实现
collectionView:layout:minimumLineSpacingForSectionAtIndex:
和collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
这两个delegate
方法
指定inset:
- 通过
sectionInset
属性 - 通过
- (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
方法,在更改属性,最后将属性返回。
<b>实例</b>:
//该方法返回一个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 也许你想添加新的布局属性
- 继承
UICollectionViewLayoutAttributes
,实现自己的LayoutAttributes
,然后可以添加任何你需要的布局信息作为它的属性。
- 在自定义的
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。除非是如下情况,否则不建议自定义:
- 你所想实现的外观并不是网格或者
line-based breaking
布局(items排成一行直到行满,再继续往下一行上去排,直到所有items都排列完成),或者必须要在多个方向上都可以滚动 - 需要频繁地改变所有
Cell
的位置,以致于创建自定义layout
比修改现有flow layout
工作量更省
4.2 继承UICollectionViewLayout
继承UICollectionViewLayout
之后只需要重载几个提供布局核心特性的方法,其他方法只需按情况重载即可,核心特性如下:
- 指定可滚动内容区域的
size
- 为布局中的每个
Cell
及view
提供属性对象