UICollectionView是一種類似于UITableView但又比UITableView功能更強大骇扇、更靈活的視圖,這是源于它將UICollectionView對cell的布局交給了UICollectionViewLayout,而且允許用戶自定義layout來進行布局。
下面是UICollectionView合并內容和布局并生成最終界面的一個流程:
當UICollectionView顯示內容時,先從Data source(數據源)獲取cell飞几,然后交給UICollectionView。再從UICollectionViewLayout獲取對應的layout attributes(布局屬性)独撇。最后屑墨,根據每個cell對應的layout attributes(布局屬性)來對cell進行布局,生成了最終的界面纷铣。而用戶交互的時候卵史,都是通過Delegate來進行交互。當然搜立,上面只是布局cell墙杯,但是UICollectionView內部還有Supplementary View和Decoration View刺桃,也可以對其進行布局刽严。
上面皇筛,我們了解了UICollectionView的工作流程色鸳,我們將UICollectionView分成視圖社痛、數據源和代理方法、UICollectionViewLayout三塊來介紹命雀。
一蒜哀、視圖
UICollectionView上面顯示內容的視圖有三種Cell視圖、Supplementary View和Decoration View吏砂。
Cell視圖
CollectionView中主要的內容都是由它展示的撵儿,它是從數據源對象獲取的。
Supplementary View
它展示了每一組當中的信息狐血,與cell類似淀歇,它是從數據源方法當中獲取的,但是與cell不同的是匈织,它并不是強制需要的浪默。例如flow layout當中的headers和footers就是可選的Supplementary View。
Decoration View
這個視圖是一個裝飾視圖缀匕,它沒有什么功能性纳决,它不跟數據源有任何關系,它完全屬于layout對象乡小。
二阔加、數據源和代理方法
1、注冊cell或者Supplementary View使其重用
在使用數據源返回cell或者Supplementary View給collectionView之前满钟,我們必須先要注冊胜榔,用來進行重用胳喷。
registerClass: forCellWithReuseIdentifier:
registerNib: forCellWithReuseIdentifier:
registerClass: forSupplementaryViewOfKind: withReuseIdentifier:
registerNib: forSupplementaryViewOfKind: withReuseIdentifier:
顯而易見,前面兩個方法是注冊cell苗分,后兩個方法注冊Supplementary View厌蔽。其中,注冊的方式有兩種摔癣,第一種是直接注冊class奴饮,它重用的時候會調用[[UICollectionView alloc] init]這樣的初始化方法創(chuàng)建cell;另外一種是注冊nib择浊,它會自動加載nib文件戴卜。
注冊的之后,我們如何重用琢岩?
在數據源方法當中返回 cell 或者 Supplementary view 的方法當中通過 dequeueReusableCellWithReuseIdentifier:forIndexPath: 或者 dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: 方法獲取cell或者Supplementary View投剥。
示例代碼:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentify forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightGrayColor];
cell.textLabel.text = [NSString stringWithFormat:@"(%zd,%zd)", indexPath.section, indexPath.row];
return cell;
}
2、數據源方法
數據源方法與UITableView類似担孔,主要有:
numberOfSectionsInCollectionView:
collectionView: numberOfItemsInSection:
collectionView: cellForItemAtIndexPath:
collectionView: viewForSupplementaryElementOfKind: atIndexPath:
與UITableView不同的是多加了返回Supplementary view數據源方法江锨。
3、代理方法
數據源為UICollectionView提供數據相關的內容糕篇,而代理則主要負責用戶交互啄育、與數據無關的視圖外形。主要分成兩部分:
1拌消、通過調用代理方法挑豌,管理視圖的選中、高亮
collectionView:shouldDeselectItemAtIndexPath:
collectionView:didSelectItemAtIndexPath:
collectionView:didDeselectItemAtIndexPath:
collectionView:shouldHighlightItemAtIndexPath:
collectionView:didHighlightItemAtIndexPath:
collectionView:didUnhighlightItemAtIndexPath:
2墩崩、長按cell氓英,顯示編輯菜單 當用戶長按cell時,collection view視圖會顯示一個編輯菜單鹦筹。這個編輯菜單可以用來剪切铝阐、復制和粘貼cell。不過铐拐,要顯示這個編輯菜單需要滿足很多條件:
代理對象必須實現下面三個方法:
collectionView:shouldShowMenuForItemAtIndexPath: collectionView:canPerformAction:forItemAtIndexPath:withSender: collectionView:performAction:forItemAtIndexPath:withSender:
對于指定要編輯的cell饰迹, collectionView:shouldShowMenuForItemAtIndexPath: 方法需要返回 YES
collectionView:canPerformAction:forItemAtIndexPath:withSender: 方法中,對于剪切余舶、復制啊鸭、粘貼三種action至少有一個返回YES。其實匿值,編輯菜單是有很多種action的赠制,但是對于UICollectionView來說,它僅僅支持的剪切、復制钟些、粘貼三個烟号,所以說這個代理方法至少支持這三種的一種。
剪切政恍、復制汪拥、粘貼的方法名是:
cut: copy: paste:
當上面的條件都滿足了,用戶就可以長按cell顯示出編輯菜單篙耗,然后選擇對應的action迫筑,從而就會回調delegate的collectionView:performAction:forItemAtIndexPath:withSender: 方法去做對應的事情。
當我們想控制編輯菜單僅僅顯示復制和粘貼時宗弯,我們就可以在 collectionView:canPerformAction:forItemAtIndexPath:withSender: 方法中進行操作脯燃,具體請見下面代碼:
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender{
if ([NSStringFromSelector(action) isEqualToString:@"copy:"]
|| [NSStringFromSelector(action) isEqualToString:@"paste:"])
return YES;
return NO;
}
三、UICollectionViewLayout
UICollectionViewLayout 是UICollectionView比UITableView更強大原因蒙保,它是UICollectionView的精髓辕棚,它通過 UICollectionViewLayoutAttributes 類來管理 cell 、 Supplementary View 和 Decoration View 的 位置 邓厕、 transform 逝嚎、 alpha 、 hidden 等等详恼。
UICollectionViewLayout這個類只是一個基類懈糯,我們給UICollectionView使用的都是它的 子類 。系統為我們提供了一個最常用的layout為 UICollectionViewFlowLayout 单雾,我們可以使用它制作 grid view 。當UICollectionViewLayout滿足不了我們的需求時她紫,我們可以 子類化UICollectionViewLayout 或者 自定義layout 硅堆,這個內容放到我下一篇當中。
下面贿讹,我們來看看怎么使用UICollectionViewFlowLayout渐逃。 使用UICollectionViewFlowLayout之前,我們來了解它內部常用的屬性:
//同一組當中民褂,行與行之間的最小行間距茄菊,但是不同組之間的不同行cell不受這個值影響。
@property (nonatomic) CGFloat minimumLineSpacing;
//同一行的cell中互相之間的最小間隔赊堪,設置這個值之后面殖,那么cell與cell之間至少為這個值
@property (nonatomic) CGFloat minimumInteritemSpacing;
//每個cell統一尺寸
@property (nonatomic) CGSize itemSize;
//滑動反向,默認滑動方向是垂直方向滑動
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
//每一組頭視圖的尺寸哭廉。如果是垂直方向滑動脊僚,則只有高起作用;如果是水平方向滑動遵绰,則只有寬起作用辽幌。
@property (nonatomic) CGSize headerReferenceSize;
//每一組尾部視圖的尺寸增淹。如果是垂直方向滑動,則只有高起作用乌企;如果是水平方向滑動虑润,則只有寬起作用。
@property (nonatomic) CGSize footerReferenceSize;
//每一組的內容縮進
@property (nonatomic) UIEdgeInsets sectionInset;
上面是UICollectionViewFlowLayout內部的屬性加酵,這些屬性都是統一設置拳喻,若是統一設置無法滿足需求,可以實現 UICollectionViewDelegateFlowLayout 方法虽画,進行對應的設置舞蔽。
了解了UICollectionViewFlowLayout主要屬性,我們再來看看使用步驟:
1码撰、生成一個UICollectionViewFlowLayout對象給collection view
2渗柿、通過itemSize來配置cell的寬和高
3、如果有需要通過設置minimumInteritemSpacing來設置每個cell之間的間距脖岛,通過minimumLineSpacing來設置同一組當中不同行之間cell的行距朵栖。
4、如果想要組頭視圖或者組尾視圖柴梆,指定它們的大小
5陨溅、設置layout的滑動方向
6、如果統一設置無法滿足需求绍在,實現UICollectionViewDelegateFlowLayout方法來進行設置门扇。