iOS UIKit:CollectionView之布局(2)
Collection view使用UICollectionViewFlowLayout对象来管理section中的cell,该对象是一种流布局方式,即在collection view中的section之间默认是往垂直方向分布,但在section中的cell则是往水平方向排列,若在一行中没有足够的空间容纳section的所有cell,则将剩下的cell放在下一行,如图 31所示。
图 31 Laying out sections and cells using the flow layout
1 类结构
UICollectionView类中有一个名为collectionViewLayout的属性,其为UICollectionViewLayout类型的抽象类,该属性的功能是管理collection view中的section和cell的布局,其默认值的类型为UICollectionViewFlowLayout类。
UICollectionViewFlowLayout类继承了抽象类UICollectionViewLayout,从而可以创建一个新的UICollectionViewFlowLayout对象赋值给collection view的collectionViewLayout属性,从而修改collection view的布局。
表 31 UICollectionViewFlowLayout类的成员属性
属性名 |
类型 |
描述 |
minimumLineSpacing |
CGFloat |
在同一个section中line之间的最小间隙,默认为0。实际值可能大于该值,但不能比其小。 |
minimumInteritemSpacing |
CGFloat |
在同一行的line中item(cell)之间的最小间隙,实际值可能大于该值,但不能比其小。 |
itemSize |
CGSize |
该值定义了每个item(cell)的长宽值。 |
estimatedItemSize |
CGSize |
估计cell的长宽值。 |
scrollDirection |
UICollectionViewScrollDirection |
Collection view的滚动方向,默认为垂直方向,可以通过修改该属性来改变滚动的方向。 |
headerReferenceSize |
CGSize |
Section的header视图的长宽值。 |
footerReferenceSize |
CGSize |
Section的footer视图的长宽值。 |
sectionInset |
UIEdgeInsets |
Section的上、下、左、右边缘的空隙值。 |
可使用programmatically或Interface Builder方式来配置flow layout object,都按如下步骤进行配置:
a) 创建一个flow layout object,并将其赋值给collection view;
b) 配置cell对象的高宽值;
c) 若需要可以设置item之间的间隙;
d) 如果希望设置section的header和footer,可以设置其尺寸;
e) 设置collection的滚动方向
如下通过获取collection view的collectionViewLayout属性,从而修改其原来的布局:
2 [super viewDidLoad];
3 _array = [[NSMutableArray alloc] initWithObjects:
4 [NSMutableArray arrayWithObjects:@"Item1", @"Item2", nil],
5 [NSMutableArray arrayWithObjects:@"Item1", @"Item2", @"Item3", nil],
6 [NSMutableArray arrayWithObjects:@"Item1", @"Item2", @"Item3", @"Item4", nil],
7 [NSMutableArray arrayWithObjects:@"Item1", @"Item2", @"Item3", @"Item4", @"Item5",nil],
8 nil];
9
10 UICollectionViewFlowLayout *layout = self.collectionView.collectionViewLayout;
11 UIEdgeInsets edge = UIEdgeInsetsMake(20, 20, 20, 20);
12 layout.sectionInset = edge;
13 layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
14 }
注意:
最低限度必须指定cell对象的高度和宽度,因为cell的默认值是为0,若不指定cell对象的高宽值,则它们将不可见。
2 自定义
用户可以修改UICollectionView对象的collectionViewLayout属性,从而改变collection view的流布局,其中该属性为UICollectionViewFlowLayout类型,其成员列表如表 31所示。但改变collectionViewLayout属性后会出现所有的cell和section都拥有相同的布局,若希望对某些cell或section对象进行特殊布局,那么可以在赋值给collection view 的delegate对象中,实现UICollectionViewDelegateFlowLayout协议的某些方法,从而进行特殊化布局。
2.1 Item尺寸
collection view中的所有item(cell)都是一个相同大小的矩形,如果希望根据不同的cell指定不同的大小,必须在collection view delegate中实现collectionView:layout:sizeForItemAtIndexPath:方法,从而根据NSIndexPath参数返回不同的CGSize大小。注意在同一水平线上的cell是居中对齐的,如图 32所示。
图 32 Items of different sizes in the flow layout
如下所示,根据奇偶列不同,设置不同的cell大小。
2 sizeForItemAtIndexPath:(NSIndexPath *)indexPath
3 {
4 CGSize size;
5 if (indexPath.item%2 == 0) {
6 size = CGSizeMake(100, 100);
7 }
8 else
9 {
10 size = CGSizeMake(150, 150);
11 }
12 return size;
13 }
2.2 Item间隙
UICollectionViewFlowLayout类有个minimumInteritemSpacing属性,其描述同一line中相邻两个Item之间的最小距离,如图 33所示的绿线。用户可以在collection view delegate中实现collectionView:layout:minimumInteritemSpacingForSectionAtIndex:方法,从而自定义同一line中两个item之间的最小距离。
图 33 Actual spacing between items may be greater than the minimum
如下所示,第一个section中的item之间的距离设为10,其它的section设为5;
2 minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
3 {
4 if(section == 0)
5 return 10;
6 else
7 return 5;
8 }
2.3 Line间隙
UICollectionViewFlowLayout类有个minimumLineSpacing属性,其描述同一个section中相邻两line之间的最小距离,如图 34所示的绿线。用户可以在collection view delegate中实现collectionView:layout:minimumLineSpacingForSectionAtIndex:方法,从而自定义同一个section中相邻两line之间的最小距离。
图 34 Line spacing varies if items are of different sizes
如下所示,若第4个section(从0开始)中有多line,则line之间的最小距离为5,其它的为0。
2 minimumLineSpacingForSectionAtIndex:(NSInteger)section
3 {
4 if (section == 3) {
5 return 5;
6 }
7 return 0;
8 }
2.4 Section边距
在section中的cell距离边界有上、下、左和右四个方位的距离,如图 35所示蓝色矩形为一个个cell对象,其中默认为0。若希望自定义边距大小,可以在collection view delegate中实现 collectionView:layout:insetForSectionAtIndex:方法,从而返回section四个方位的大小。
图 35 Section insets change the available space for laying out cells
如下所示,修改每个section的边距。
2 insetForSectionAtIndex:(NSInteger)section
3 {
4 UIEdgeInsets edge = UIEdgeInsetsMake(20, 20, 20, 20);
5 return edge;
6 }
2.5 Header和Footer尺寸
每个section都有一个header视图和一个Footer视图,如图 35所示,可以通过collection view delegate协议提供的 collectionView:layout:referenceSizeForHeaderInSection:方法和
collectionView:layout:referenceSizeForFooterInSection方法来改变section的header视图或Footer视图的尺寸。
如下所示第一个section的header尺寸进行特殊化处理。
2 referenceSizeForHeaderInSection:(NSInteger)section
3 {
4 if (section == 0) {
5 return CGSizeMake(20, 20);
6 }
7 return CGSizeMake(0, 0);
8 }
3 参考文献
[1] Collection View Programming Guide for IOS.