UICollectionView是一種新的數據展現方式,簡單來講能夠把他理解成多列的UITableView(請必定注意這是UICollectionView的最最簡單的形式)。若是你用過iBooks的話,可能你還對書架佈局有必定印象:一個虛擬書架上放着你下載和購買的各種圖書,整齊排列。其實這就是一個UICollectionView的表現形式,或者iPad的iOS6中的原生時鐘應用中的各個時鐘,也是UICollectionView的最簡單的一個佈局,如圖:設計模式
最簡單的UICollectionView就是一個GridView,能夠以多列的方式將數據進行展現。標準的UICollectionView包含三個部分,它們都是UIView的子類:app
無論一個UICollectionView的佈局如何變化,這三個部件都是存在的。再次說明,複雜的UICollectionView毫不止上面的幾幅圖,關於較複雜的佈局和相應的特性,我會在本文稍後和下一篇筆記中進行一些深刻。佈局
先從最簡單的開始,UITableView是iOS開發中的很是很是很是重要的一個類,相信若是你是開發者的話應該是對這個類很是熟悉了。實現一個UICollectionView和實現一個UITableView基本沒有什麼大區別,它們都一樣是datasource和delegate設計模式的:datasource爲view提供數據源,告訴view要顯示些什麼東西以及如何顯示它們,delegate提供一些樣式的小細節以及用戶交互的相應。所以在本節裏會大量對比collection view和table view來進行說明,若是您還不太熟悉table view的話,也是個對照着複習的好機會。動畫
實現以上三個委託方法,基本上就能夠保證CollectionView工做正常了。固然,還有提供Supplementary View的方法ui
對於Decoration Views,提供方法並不在UICollectionViewDataSource中,而是直接在UICollectionViewLayout類中的(由於它僅僅是視圖相關,而與數據無關),放到稍後再說。spa
爲了獲得高效的View,對於cell的重用是必須的,避免了不斷生成和銷燬對象的操做,這與在UITableView中的狀況是一致的。但值得注意的時,在UICollectionView中,不只cell能夠重用,Supplementary View和Decoration View也是能夠而且應當被重用的。在iOS5中,Apple對UITableView的重用作了簡化,以往要寫相似這樣的代碼:設計
1
2
3
4
5
6
|
UITableViewCell
*cell
=
[
tableView
dequeueReusableCellWithIdentifier
:
@"MY_CELL_ID"
]
;
if
(
!
cell
)
//若是沒有可重用的cell,那麼生成一個 {
cell
=
[
[
UITableViewCell
alloc
]
init
]
;
}
//配置cell,blablabla
return
cell
;
|
而若是咱們在TableView向數據源請求數據以前使用-registerNib:forCellReuseIdentifier:方法爲@「MY_CELL_ID」註冊過nib的話,就能夠省下每次判斷並初始化cell的代碼,要是在重用隊列裏沒有可用的cell的話,runtime將自動幫咱們生成並初始化一個可用的cell。code
這個特性很受歡迎,所以在UICollectionView中Apple繼承使用了這個特性,而且把其進行了一些擴展。使用如下方法進行註冊:orm
相比UITableView有兩個主要變化:一是加入了對某個Class的註冊,這樣即便不用提供nib而是用代碼生成的view也能夠被接受爲cell了;二是不只只是cell,Supplementary View也能夠用註冊的方法綁定初始化了。在對collection view的重用ID註冊後,就能夠像UITableView那樣簡單的寫cell配置了:對象
1
2
3
4
5
6
|
-
(
UICollectionView
*
)
collectionView
:
(
UICollectionView
*
)
cv
cellForItemAtIndexPath
:
(
NSIndexPath
*
)
indexPath
{
MyCell
*cell
=
[
cv
dequeueReusableCellWithReuseIdentifier
:
@」
MY_CELL_ID」
]
;
// Configure the cell's content
cell
.
imageView
.
image
=
.
.
.
return
cell
;
}
|
須要吐槽的是,對collection view,取重用隊列的方法的名字和UITableView裏面不同了,在Identifier前面多加了Reuse五個字母,語義上要比之前清晰,命名規則也比之前嚴謹了..不知道Apple會不會爲了追求完美而把UITableView中的命名不那麼好的方法deprecate掉。
數據無關的view的外形啊,用戶交互啊什麼的,由UICollectionViewDelegate來負責:
關於用戶交互,UICollectionView也作了改進。每一個cell如今有獨立的高亮事件和選中事件的delegate,用戶點擊cell的時候,如今會按照如下流程向delegate進行詢問:
狀態控制要比之前靈活一些,對應的高亮和選中狀態分別由highlighted和selected兩個屬性表示。
相對於UITableViewCell來講,UICollectionViewCell沒有這麼多花頭。首先UICollectionViewCell不存在各式各樣的默認的style,這主要是因爲展現對象的性質決定的,由於UICollectionView所用來展現的對象相比UITableView來講要來得靈活,大部分狀況下更偏向於圖像而非文字,所以需求將會千奇百怪。所以SDK提供給咱們的默認的UICollectionViewCell結構上相對比較簡單,由下至上:
此次Apple給咱們帶來的好康是被選中cell的自動變化,全部的cell中的子view,也包括contentView中的子view,在當cell被選中時,會自動去查找view是否有被選中狀態下的改變。好比在contentView里加了一個normal和selected指定了不一樣圖片的imageView,那麼選中這個cell的同時這張圖片也會從normal變成selected,而不須要額外的任何代碼。
終於到UICollectionView的精髓了…這也是UICollectionView和UITableView最大的不一樣。UICollectionViewLayout能夠說是UICollectionView的大腦和中樞,它負責了將各個cell、Supplementary View和Decoration Views進行組織,爲它們設定各自的屬性,包括但不限於:
Layout決定了UICollectionView是如何顯示在界面上的。在展現以前,通常須要生成合適的UICollectionViewLayout子類對象,並將其賦予CollectionView的collectionViewLayout屬性。關於詳細的自定義UICollectionViewLayout和一些細節,我將寫在以後一篇筆記中。
Apple爲咱們提供了一個最簡單可能也是最經常使用的默認layout對象,UICollectionViewFlowLayout。Flow Layout簡單說是一個直線對齊的layout,最多見的Grid View形式即爲一種Flow Layout配置。上面的照片架界面就是一個典型的Flow Layout。
一個UICollectionView的實現包括兩個必要部分:UICollectionViewDataSource和UICollectionViewLayout,和一個交互部分:UICollectionViewDelegate。而Apple給出的UICollectionViewFlowLayout已是一個很強力的layout方案了。
可是光是UICollectionViewFlowLayout的話,顯然是不夠用的,並且若是單單是這樣的話,就和現有的開源各種Grid View沒有區別了…UICollectionView的強大之處,就在於各類layout的自定義實現,以及它們之間的切換。先看幾個至關exiciting的例子吧~
好比,堆疊佈局:
圓形佈局:
和Cover Flow佈局:
全部這些佈局都採用了一樣的數據源和委託方法,所以徹底實現了model和view的解耦。可是若是僅這樣,那開源社區也已經有不少相應的解決方案了。Apple的強大和開源社區不能比擬的地方在於對SDK的全局掌控,CollectionView提供了很是簡單的API能夠令開發者只須要一次簡單調用,就可使用CoreAnimation在不一樣的layout之間進行動畫切換,這種切換一定將大幅增長用戶體驗,代價只是幾十行代碼就能完成的佈局實現,以及簡單的一句API調用,不得不說如今全部的開源代碼與之相比,都是相形見拙了…不得不佩服和感謝UIKit團隊的努力。