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.