你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> UICollectionView之介紹使用篇

UICollectionView之介紹使用篇

編輯:IOS開發基礎

43.jpg

43.jpg

作者:liuchungui

實現垂直方向的單列表來說,使用UITableView足以;若是需要構建橫向滑動列表、gridView等直線型布局,則使用UICollectionView+UICollectionViewFlowLayout搭建最合適;更復雜的布局,則可以使用UICollectionView+自定義Layout來實現。

而這篇博客就來介紹一下UICollectionView。

首先,來了解一下UICollectionView工作流程:

QQ截圖20160205112450.png

當UICollectionView顯示內容時,先從數據源獲取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,顯示編輯菜單 與UITableView不同,用戶長按cell時,UICollectionView可以顯示編輯菜單。這個編輯菜單可以用來剪切、復制和粘貼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是通過UICollectionViewLayoutAttributes類來管理cell、Supplementary View和Decoration View的位置、transform、alpha、hidden等等。 
UICollectionViewLayout這個類只是一個基類,我們給UICollectionView使用的都是它的子類。系統為我們提供了一個最常用的layout為UICollectionViewFlowLayout,我們可以使用它制作grid view。當UICollectionViewLayout滿足不了我們的需求時,我們可以子類化UICollectionViewLayout或者自定義layout,這個內容放到我下一篇當中。

UICollectionViewFlowLayout

使用UICollectionViewFlowLayout之前,我們來了解它內部常用的屬性:

//同一組當中,垂直方向:行與行之間的間距;水平方向:列與列之間的間距
@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的屬性來敘述,請自行參照修改。

UICollectionViewFlowLayout在縱向滑動與橫向滑動時,布局是不太一樣的。

QQ截圖20160205113024.png

由上圖就可以看出來,UICollectionViewFlowLayout在布局時,會根據scrollDirection的值不同而產生不同的布局。

  • 垂直方向滑動:

Cell布局:UICollectionView的內容寬度與本身視圖的寬度相等,並且是固定的。會根據sectionInset左右縮進、itemSize的寬度、minimumInteritemSpacing三個值來計算每一行cell數量。 
具體計算公式是: 
cellCount = (CollectionViewContentWidth-sectionInset.left-sectionInset.right+minimumInteritemSpacing)/(itemSize.width+minimumInteritemSpacing)CollectionViewContentWidth是UICollectionView的內容寬度,計算出來的cellCount進行四捨五入成一個整數就是每一行cell的數量。 
而每個cell之間實際的間隔值則是: 
realInteritemSpacing = (CollectionViewContentWidth-sectionInset.left-sectionInset.right-cellCount*itemSize.width)/(cellCount-1)
當每個cell大小確定、每一行cell的個數確定、每個cell之間的間距確定之後,UICollectionViewFlowLayout就可以計算出每一行cell的frame了。 
而如果同一組cell的個數,在水平方向的一行放不下去,則就會放入第二行,而這第二行的cell在垂直方向與第一行的cell相隔minimumLineSpacing。這樣又確定了行與行之間的間距,那麼這一組cell的布局就可以確定了。

頭視圖與尾部視圖:根據headerReferenceSize和footerReferenceSize中的高來確定頭部和尾部視圖的高,它其實就是兩個不同類型的Supplementary View。

  • 水平方向滑動:

Cell布局:水平方向的滑動內容的高與本身視圖的高是相等的,並且是固定的。它的cell是從上到下進行布局的。會根據sectionInset上下縮進、itemSize的高度、minimumInteritemSpacing三個值來計算每一列放多少個cell,具體計算公式可以參照垂直方向滑動的公式。之後的邏輯和垂直方向滑動時一樣,只是minimumLineSpacing現在是代表列與列之間的間距。

頭視圖與尾部視圖:根據headerReferenceSize和footerReferenceSize中的寬來確定頭部和尾部視圖的寬。

相關使用UICollectionViewFlowLayout代碼:UICollectionViewDemo

參考

  • Collection View Programming Guide for iOS 

  • WWDC 2012 Session筆記——205 Introducing Collection Views

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved