標籤:
UICollectionView是一種類似於UITableView但又比UITableView功能更強大、更靈活的視圖,這是源於它將UICollectionView對cell的布局交給了UICollectionViewLayout,而且允許使用者自訂layout來進行布局。
當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]這樣的初始化方法建立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方法來進行設定。
iOS之UICollectionView詳解