UICollectionView簡(jiǎn)介
UICollectionView是iOS6添加的一個(gè)控件,是一種新的數(shù)據(jù)展示方式,簡(jiǎn)單來說可以把他理解成多列的UITableView,最簡(jiǎn)單的UICollectionView就是一個(gè)GridView,可以以多列的方式將數(shù)據(jù)進(jìn)行展示。
標(biāo)準(zhǔn)的UICollectionView包含三個(gè)部分,它們都是UIView的子類:
Cells 用于展示內(nèi)容的主體,對(duì)于不同的cell可以指定不同尺寸和不同的內(nèi)容
Supplementary Views 追加視圖,可以理解為每個(gè)Section的Header或者Footer,用來標(biāo)記每個(gè)section的view
Decoration Views 裝飾視圖 這是每個(gè)section的背景
實(shí)現(xiàn)一個(gè)簡(jiǎn)單的UICollectionView
實(shí)現(xiàn)一個(gè)UICollectionView和實(shí)現(xiàn)一個(gè)UITableView基本沒有什么大區(qū)別,它們都同樣是datasource+delegate
基本的UICollectionViewDataSource提供
<pre><code>
-numberOfSectionsInCollection: //section的數(shù)量
-collectionView:numberOfItemsInSection: //某個(gè)section里有多少個(gè)item
-collectionView:cellForItemAtIndexPath: // 對(duì)于某個(gè)位置應(yīng)該顯示什么樣的cell
-collectionView:viewForSupplementaryElementOfKind:atIndexPath: //提供Supplementary View
</code></pre>
與UITableView中的情況一致,UICollectionView也需要對(duì)Cell進(jìn)行重用,在iOS5中,Apple對(duì)UITableView的重用做了簡(jiǎn)化,以往要寫類似這樣的代碼:
<pre><code>
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MY_CELL_ID"];
if (!cell) {
cell = [[UITableViewCell alloc] init];
}
//配置cell,blablabla
return cell
</code></pre>
在iOS5以后如果我們?cè)赥ableView向數(shù)據(jù)源請(qǐng)求數(shù)據(jù)之前使用-registerNib:forCellReuseIdentifier:方法為@“MYCELLID"注冊(cè)過nib的話,就可以省下每次判斷并初始化cell的代碼,要是在重用隊(duì)列里沒有可用的cell的話,runtime將自動(dòng)幫我們生成并初始化一個(gè)可用的cell,還有以下類似方法
<pre><code>
(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
(void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
(void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
(void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
</code></pre>
同樣的 UICollectionView也有類似的方法
<pre><code>
(void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
(void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
(void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
(void)registerNib:(UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
</code></pre>
基本的UICollectionViewDelegate提供與數(shù)據(jù)無關(guān)的view的外形,用戶交互之類:
cell的高亮
cell的選中狀態(tài)
可以支持長(zhǎng)按后的菜單
關(guān)于用戶交互,UICollectionView也做了改進(jìn)。每個(gè)cell現(xiàn)在有獨(dú)立的高亮事件和選中事件的delegate,用戶點(diǎn)擊cell的時(shí)候,現(xiàn)在會(huì)按照以下流程向delegate進(jìn)行詢問:
<pre><code>
-collectionView:shouldHighlightItemAtIndexPath: // 是否應(yīng)該高亮?
-collectionView:didHighlightItemAtIndexPath: //如果1答是,那么高亮
-collectionView:shouldSelectItemAtIndexPath: //無論1結(jié)果如何,都詢問是否可以被選中?
-collectionView:didUnhighlightItemAtIndexPath: // 如果1答是,那么現(xiàn)在取消高亮
-collectionView:didSelectItemAtIndexPath: // 如果3答是,那么選中cell
</code></pre>
Cell
UICollectionViewCell結(jié)構(gòu)比較簡(jiǎn)單, 由上至下
首先是cell本身作為容器view
然后是一個(gè)大小自動(dòng)適應(yīng)整個(gè)cell的backgroundView,用作cell平時(shí)的背景
再其上是selectedBackgroundView,是cell被選中時(shí)的背景
最后是一個(gè)contentView,自定義內(nèi)容應(yīng)被加在這個(gè)view上
UICollectionViewLayout
這是UICollectionView和UITableView最大的不同。UICollectionViewLayout負(fù)責(zé)了將各個(gè)cell、Supplementary View和Decoration Views進(jìn)行組織,為它們?cè)O(shè)定各自的屬性。在展示之前,一般需要生成合適的UICollectionViewLayout子類對(duì)象,并將其賦予CollectionView的collectionViewLayout屬性。
SDK為我們提供了一個(gè)最簡(jiǎn)單可能也是最常用的默認(rèn)layout對(duì)象,UICollectionViewFlowLayout。Flow Layout簡(jiǎn)單說是一個(gè)直線對(duì)齊的layout,最常見的Grid View形式即為一種Flow Layout配置:
首先一個(gè)重要的屬性是itemSize,它定義了每一個(gè)item的大小。通過設(shè)定itemSize可以全局地改變所有cell的尺寸,如果想要對(duì)某個(gè)cell制定尺寸,可以使用-collectionView:layout:sizeForItemAtIndexPath:方法。
間隔 可以指定item之間的間隔和每一行之間的間隔,和size類似,有全局屬性,也可以對(duì)每一個(gè)item和每一個(gè)section做出設(shè)定:
<pre><code>
@property (CGSize) minimumInteritemSpacing
@property (CGSize) minimumLineSpacing
-collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
-collectionView:layout:minimumLineSpacingForSectionAtIndex:
</code></pre>
滾動(dòng)方向 由屬性scrollDirection確定scroll view的方向,將影響Flow Layout的基本方向和由header及footer確定的section之間的寬度
UICollectionViewScrollDirectionVertical
UICollectionViewScrollDirectionHorizontal
Header和Footer尺寸 同樣地分為全局和部分。需要注意根據(jù)滾動(dòng)方向不同,header和footer的高和寬中只有一個(gè)會(huì)起作用。垂直滾動(dòng)時(shí)section間寬度為該尺寸的高,而水平滾動(dòng)時(shí)為寬度起作用,如圖。
<pre><code>
@property (CGSize) headerReferenceSize
@property (CGSize) footerReferenceSize
-collectionView:layout:referenceSizeForHeaderInSection:
-collectionView:layout:referenceSizeForFooterInSection:
</code></pre>
縮進(jìn)
<pre><code>
@property UIEdgeInsets sectionInset;
-collectionView:layout:insetForSectionAtIndex:
</code></pre>
通過自定義Layout可以實(shí)現(xiàn)各種nb布局,基本上常見的類似的第三方開源控件效果都可以實(shí)現(xiàn),比如瀑布流、coverFlow,下面實(shí)現(xiàn)一個(gè)基本的瀑流效果